Add the data-line filter

This commit is contained in:
Rodolphe Bréard 2020-11-28 12:10:22 +01:00
parent 0a4ac5a709
commit 1ac792ed6b
6 changed files with 33 additions and 37 deletions

8
src/data_line.rs Normal file
View file

@ -0,0 +1,8 @@
use crate::FilterEntry;
use std::io::{self, Write};
pub fn return_data_line(entry: &FilterEntry, data_line: &[u8]) {
print!("filter-dataline|{}|{}|", entry.session_id, entry.token);
io::stdout().write_all(data_line).unwrap();
println!("");
}

View file

@ -43,6 +43,12 @@ pub trait Filter {
return false;
}
fn on_filter_data_line(&mut self, _entry: &FilterEntry, _data_line: &[u8]) {}
#[doc(hidden)]
fn has_filter_data_line(&self) -> bool {
return false;
}
fn on_filter_ehlo(&mut self, _entry: &FilterEntry, _identity: &str) -> FilterResponse {
FilterResponse::Proceed
}

View file

@ -43,12 +43,14 @@
//!
//! More examples can be found in the [examples directory](https://github.com/breard-r/rust-opensmtpd/tree/main/examples).
mod data_line;
mod data_structures;
mod filter;
mod io;
mod parsers;
mod process;
pub use crate::data_line::return_data_line;
pub use crate::data_structures::address::Address;
pub use crate::data_structures::auth_result::AuthResult;
pub use crate::data_structures::event::Event;

View file

@ -26,22 +26,13 @@ pub struct FilterEntry {
pub token: String,
}
pub struct DataLineEntry {
pub session_id: String,
pub token: String,
}
pub(crate) enum EntryOption {
Report(ReportEntry),
Filter(FilterEntry),
DataLine(DataLineEntry),
}
pub(crate) fn parse_entry(input: &[u8]) -> IResult<&[u8], EntryOption> {
let (input, entry) = alt((
parse_report_entry_meta,
alt((parse_filter_entry_meta, parse_data_line_entry_meta)),
))(input)?;
let (input, entry) = alt((parse_report_entry_meta, parse_filter_entry_meta))(input)?;
Ok((input, entry))
}
@ -59,13 +50,6 @@ fn parse_filter_entry_meta(input: &[u8]) -> IResult<&[u8], EntryOption> {
Ok((input, EntryOption::Filter(entry)))
}
fn parse_data_line_entry_meta(input: &[u8]) -> IResult<&[u8], EntryOption> {
let (input, _) = tag("filter-dataline")(input)?;
let (input, _) = parse_delimiter(input)?;
let (input, data_line) = parse_data_line_entry(input)?;
Ok((input, EntryOption::DataLine(data_line)))
}
fn parse_report_entry(input: &[u8]) -> IResult<&[u8], ReportEntry> {
let (input, version) = parse_string_parameter(input)?;
let (input, _) = parse_delimiter(input)?;
@ -109,14 +93,6 @@ fn parse_filter_entry(input: &[u8]) -> IResult<&[u8], FilterEntry> {
Ok((input, entry))
}
fn parse_data_line_entry(input: &[u8]) -> IResult<&[u8], DataLineEntry> {
let (input, session_id) = parse_string_parameter(input)?;
let (input, _) = parse_delimiter(input)?;
let (input, token) = parse_string_parameter(input)?;
let entry = DataLineEntry { session_id, token };
Ok((input, entry))
}
fn parse_timestamp(input: &[u8]) -> IResult<&[u8], TimeVal> {
let (input, sec) = map_res(digit1, |s| String::from_utf8_lossy(s).parse::<i64>())(input)?;
let (input, _) = tag(".")(input)?;

View file

@ -1,6 +1,6 @@
use super::{
is_parameter_char, parse_data_structure, parse_delimiter, parse_eol, parse_string_parameter,
parse_usize,
is_body_char, is_parameter_char, parse_data_structure, parse_delimiter, parse_eol,
parse_string_parameter, parse_usize,
};
use crate::{Address, AuthResult, FilterKind, FilterPhase, MailResult, Method};
use nom::branch::alt;
@ -32,6 +32,13 @@ pub(crate) fn parse_filter_connect(
Ok((input, (rdns, fcrdns, src, dest)))
}
pub(crate) fn parse_filter_data_line(input: &[u8]) -> IResult<&[u8], &[u8]> {
let (input, _) = parse_delimiter(input)?;
let (input, s) = take_while1(is_body_char)(input)?;
let (input, _) = parse_eol(input)?;
Ok((input, s))
}
pub(crate) fn parse_filter_ehlo(input: &[u8]) -> IResult<&[u8], String> {
let (input, _) = parse_delimiter(input)?;
let (input, s) = parse_string_parameter(input)?;

View file

@ -1,7 +1,7 @@
use crate::parsers::entry::{parse_entry, EntryOption};
use crate::parsers::parameters::{
parse_filter_auth, parse_filter_connect, parse_filter_ehlo, parse_filter_helo,
parse_filter_mail_from, parse_filter_rcpt_to, parse_filter_starttls,
parse_filter_auth, parse_filter_connect, parse_filter_data_line, parse_filter_ehlo,
parse_filter_helo, parse_filter_mail_from, parse_filter_rcpt_to, parse_filter_starttls,
parse_report_filter_report, parse_report_filter_response, parse_report_link_auth,
parse_report_link_connect, parse_report_link_greeting, parse_report_link_identify,
parse_report_link_tls, parse_report_protocol_client, parse_report_protocol_server,
@ -114,7 +114,11 @@ macro_rules! handle_filters {
Some($obj.on_filter_connect(&$f, &rdns, &fcrdns, &src, &dest))
}
FilterPhase::Data => Some($obj.on_filter_data(&$f)),
FilterPhase::DataLine => None,
FilterPhase::DataLine => {
let (_, data_line) = parse_filter_data_line($input).map_err(|e| e.to_string())?;
$obj.on_filter_data_line(&$f, &data_line);
None
}
FilterPhase::Ehlo => {
let (_, identity) = parse_filter_ehlo($input).map_err(|e| e.to_string())?;
Some($obj.on_filter_ehlo(&$f, &identity))
@ -139,12 +143,6 @@ macro_rules! handle_filters {
};
}
macro_rules! handle_data_line {
($obj: ident, $f: ident, $input: ident) => {{
// TODO
}};
}
pub(crate) fn line<T>(user_object: &mut T, input: &[u8]) -> Result<(), String>
where
T: Filter,
@ -162,7 +160,6 @@ where
);
};
}
EntryOption::DataLine(l) => handle_data_line!(user_object, l, input),
};
Ok(())
}