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;
|
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 {
|
fn on_filter_ehlo(&mut self, _entry: &FilterEntry, _identity: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
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).
|
//! 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 data_structures;
|
||||||
mod filter;
|
mod filter;
|
||||||
mod io;
|
mod io;
|
||||||
mod parsers;
|
mod parsers;
|
||||||
mod process;
|
mod process;
|
||||||
|
|
||||||
|
pub use crate::data_line::return_data_line;
|
||||||
pub use crate::data_structures::address::Address;
|
pub use crate::data_structures::address::Address;
|
||||||
pub use crate::data_structures::auth_result::AuthResult;
|
pub use crate::data_structures::auth_result::AuthResult;
|
||||||
pub use crate::data_structures::event::Event;
|
pub use crate::data_structures::event::Event;
|
||||||
|
|
|
@ -26,22 +26,13 @@ pub struct FilterEntry {
|
||||||
pub token: String,
|
pub token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DataLineEntry {
|
|
||||||
pub session_id: String,
|
|
||||||
pub token: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) enum EntryOption {
|
pub(crate) enum EntryOption {
|
||||||
Report(ReportEntry),
|
Report(ReportEntry),
|
||||||
Filter(FilterEntry),
|
Filter(FilterEntry),
|
||||||
DataLine(DataLineEntry),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_entry(input: &[u8]) -> IResult<&[u8], EntryOption> {
|
pub(crate) fn parse_entry(input: &[u8]) -> IResult<&[u8], EntryOption> {
|
||||||
let (input, entry) = alt((
|
let (input, entry) = alt((parse_report_entry_meta, parse_filter_entry_meta))(input)?;
|
||||||
parse_report_entry_meta,
|
|
||||||
alt((parse_filter_entry_meta, parse_data_line_entry_meta)),
|
|
||||||
))(input)?;
|
|
||||||
Ok((input, entry))
|
Ok((input, entry))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +50,6 @@ fn parse_filter_entry_meta(input: &[u8]) -> IResult<&[u8], EntryOption> {
|
||||||
Ok((input, EntryOption::Filter(entry)))
|
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> {
|
fn parse_report_entry(input: &[u8]) -> IResult<&[u8], ReportEntry> {
|
||||||
let (input, version) = parse_string_parameter(input)?;
|
let (input, version) = parse_string_parameter(input)?;
|
||||||
let (input, _) = parse_delimiter(input)?;
|
let (input, _) = parse_delimiter(input)?;
|
||||||
|
@ -109,14 +93,6 @@ fn parse_filter_entry(input: &[u8]) -> IResult<&[u8], FilterEntry> {
|
||||||
Ok((input, entry))
|
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> {
|
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, sec) = map_res(digit1, |s| String::from_utf8_lossy(s).parse::<i64>())(input)?;
|
||||||
let (input, _) = tag(".")(input)?;
|
let (input, _) = tag(".")(input)?;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
is_parameter_char, parse_data_structure, parse_delimiter, parse_eol, parse_string_parameter,
|
is_body_char, is_parameter_char, parse_data_structure, parse_delimiter, parse_eol,
|
||||||
parse_usize,
|
parse_string_parameter, parse_usize,
|
||||||
};
|
};
|
||||||
use crate::{Address, AuthResult, FilterKind, FilterPhase, MailResult, Method};
|
use crate::{Address, AuthResult, FilterKind, FilterPhase, MailResult, Method};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
|
@ -32,6 +32,13 @@ pub(crate) fn parse_filter_connect(
|
||||||
Ok((input, (rdns, fcrdns, src, dest)))
|
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> {
|
pub(crate) fn parse_filter_ehlo(input: &[u8]) -> IResult<&[u8], String> {
|
||||||
let (input, _) = parse_delimiter(input)?;
|
let (input, _) = parse_delimiter(input)?;
|
||||||
let (input, s) = parse_string_parameter(input)?;
|
let (input, s) = parse_string_parameter(input)?;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::parsers::entry::{parse_entry, EntryOption};
|
use crate::parsers::entry::{parse_entry, EntryOption};
|
||||||
use crate::parsers::parameters::{
|
use crate::parsers::parameters::{
|
||||||
parse_filter_auth, parse_filter_connect, parse_filter_ehlo, parse_filter_helo,
|
parse_filter_auth, parse_filter_connect, parse_filter_data_line, parse_filter_ehlo,
|
||||||
parse_filter_mail_from, parse_filter_rcpt_to, parse_filter_starttls,
|
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_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_connect, parse_report_link_greeting, parse_report_link_identify,
|
||||||
parse_report_link_tls, parse_report_protocol_client, parse_report_protocol_server,
|
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))
|
Some($obj.on_filter_connect(&$f, &rdns, &fcrdns, &src, &dest))
|
||||||
}
|
}
|
||||||
FilterPhase::Data => Some($obj.on_filter_data(&$f)),
|
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 => {
|
FilterPhase::Ehlo => {
|
||||||
let (_, identity) = parse_filter_ehlo($input).map_err(|e| e.to_string())?;
|
let (_, identity) = parse_filter_ehlo($input).map_err(|e| e.to_string())?;
|
||||||
Some($obj.on_filter_ehlo(&$f, &identity))
|
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>
|
pub(crate) fn line<T>(user_object: &mut T, input: &[u8]) -> Result<(), String>
|
||||||
where
|
where
|
||||||
T: Filter,
|
T: Filter,
|
||||||
|
@ -162,7 +160,6 @@ where
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
EntryOption::DataLine(l) => handle_data_line!(user_object, l, input),
|
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue