Spam filter config adjustments

This commit is contained in:
mdecimus
2024-12-31 12:29:49 +01:00
parent 30cf967623
commit 8eda2251d8
19 changed files with 302 additions and 229 deletions

View File

@@ -7,7 +7,7 @@
use std::{future::Future, net::IpAddr};
use common::{
config::spamfilter::{Element, Location},
config::spamfilter::{Element, IpResolver, Location},
Server,
};
use mail_auth::IprevResult;
@@ -15,10 +15,7 @@ use mail_parser::{HeaderName, HeaderValue, Host};
use nlp::tokenizers::types::TokenType;
use crate::{
modules::{
dnsbl::is_dnsbl,
expression::{IpResolver, SpamFilterResolver},
},
modules::{dnsbl::is_dnsbl, expression::SpamFilterResolver},
SpamFilterContext, TextPart,
};

View File

@@ -69,7 +69,20 @@ impl SpamFilterAnalyzeLlm for Server {
confidence = Some(value);
}
} else if config.index_explanation.map_or(false, |i| i == idx) {
explanation = Some(value.replace('\n', " "));
let explanation = explanation.get_or_insert_with(|| {
String::with_capacity(std::cmp::min(value.len(), 255))
});
for value in value.chars() {
if !value.is_whitespace() {
explanation.push(value);
} else {
explanation.push(' ');
}
if explanation.len() == 255 {
break;
}
}
}
}
}
@@ -86,10 +99,9 @@ impl SpamFilterAnalyzeLlm for Server {
_ => return,
};
if let (Some(header), Some(mut explanation)) =
if let (Some(header), Some(explanation)) =
(&self.core.spam.headers.llm, explanation)
{
explanation.truncate(512);
ctx.result.header =
format!("{header}: {category} ({explanation})\r\n",).into();
}

View File

@@ -6,10 +6,13 @@
use std::future::Future;
use common::{config::spamfilter::Location, Server};
use common::{
config::spamfilter::{IpResolver, Location},
Server,
};
use crate::{
modules::expression::{EmailHeader, IpResolver, SpamFilterResolver, StringResolver},
modules::expression::{EmailHeader, SpamFilterResolver, StringResolver},
SpamFilterContext, TextPart,
};

View File

@@ -8,7 +8,7 @@ use std::collections::HashSet;
use std::hash::{Hash, Hasher};
use std::{borrow::Cow, future::Future, time::Duration};
use common::config::spamfilter::{Element, Location};
use common::config::spamfilter::{Element, IpResolver, Location};
use common::scripts::functions::unicode::CharUtils;
use common::Server;
use hyper::{header::LOCATION, Uri};
@@ -17,7 +17,7 @@ use reqwest::redirect::Policy;
use unicode_security::MixedScript;
use crate::modules::dnsbl::is_dnsbl;
use crate::modules::expression::{IpResolver, SpamFilterResolver, StringResolver};
use crate::modules::expression::{SpamFilterResolver, StringResolver};
use crate::modules::html::SRC;
use crate::{
modules::html::{HtmlToken, A, HREF},

View File

@@ -6,15 +6,18 @@
use std::{
net::Ipv4Addr,
sync::Arc,
time::{Duration, Instant},
};
use common::{config::spamfilter::DnsBlServer, expr::functions::ResolveVariable, Server};
use common::{
config::spamfilter::{DnsBlServer, IpResolver},
expr::functions::ResolveVariable,
Server,
};
use mail_auth::{common::resolver::IntoFqdn, Error};
use trc::SpamEvent;
use crate::modules::expression::IpResolver;
use super::expression::SpamFilterResolver;
pub(crate) async fn is_dnsbl(
@@ -77,13 +80,23 @@ pub(crate) async fn is_dnsbl(
Elapsed = time.elapsed()
);
let entry = Arc::new(IpResolver::new(
result
.entry
.iter()
.copied()
.next()
.unwrap_or(Ipv4Addr::BROADCAST)
.into(),
));
server.inner.cache.dns_rbl.insert_with_expiry(
zone,
Some(result.entry.clone()),
Some(entry.clone()),
result.expires,
);
result.entry
entry
}
Err(Error::DnsRecordNotFound(_)) => {
trc::event!(
@@ -118,18 +131,7 @@ pub(crate) async fn is_dnsbl(
server
.eval_if(
&config.tags,
&SpamFilterResolver::new(
resolver.ctx,
&IpResolver::new(
result
.iter()
.copied()
.next()
.unwrap_or(Ipv4Addr::BROADCAST)
.into(),
),
resolver.location,
),
&SpamFilterResolver::new(resolver.ctx, result.as_ref(), resolver.location),
resolver.ctx.input.span_id,
)
.await

View File

@@ -4,13 +4,10 @@
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use std::net::IpAddr;
use common::{
config::spamfilter::*,
expr::{functions::ResolveVariable, Variable},
};
use mail_auth::common::resolver::ToReverseName;
use mail_parser::{Header, HeaderValue};
use crate::{analysis::url::UrlParts, Recipient, SpamFilterContext, TextPart};
@@ -440,49 +437,3 @@ impl ResolveVariable for StringListResolver<'_> {
Variable::Integer(0)
}
}
pub struct IpResolver {
ip: IpAddr,
ip_string: String,
reverse: String,
octets: Variable<'static>,
}
impl ResolveVariable for IpResolver {
fn resolve_variable(&self, variable: u32) -> Variable<'_> {
match variable {
V_IP => Variable::String(self.ip_string.as_str().into()),
V_IP_REVERSE => Variable::String(self.reverse.as_str().into()),
V_IP_OCTETS => self.octets.clone(),
V_IP_IS_V4 => Variable::Integer(self.ip.is_ipv4() as _),
V_IP_IS_V6 => Variable::Integer(self.ip.is_ipv6() as _),
_ => Variable::Integer(0),
}
}
fn resolve_global(&self, _: &str) -> Variable<'_> {
Variable::Integer(0)
}
}
impl IpResolver {
pub fn new(ip: IpAddr) -> Self {
Self {
ip_string: ip.to_string(),
reverse: ip.to_reverse_name(),
octets: Variable::Array(match ip {
IpAddr::V4(ipv4_addr) => ipv4_addr
.octets()
.iter()
.map(|o| Variable::Integer(*o as _))
.collect(),
IpAddr::V6(ipv6_addr) => ipv6_addr
.octets()
.iter()
.map(|o| Variable::Integer(*o as _))
.collect(),
}),
ip,
}
}
}