Add the data-line filter
This commit is contained in:
parent
0a4ac5a709
commit
1ac792ed6b
6 changed files with 33 additions and 37 deletions
8
src/data_line.rs
Normal file
8
src/data_line.rs
Normal 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!("");
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
Reference in a new issue