Port Spam filter to Rust - part 4

This commit is contained in:
mdecimus
2024-12-10 18:56:09 +01:00
parent f0d84c8e68
commit 44ae796d9b
22 changed files with 760 additions and 477 deletions

View File

@@ -1,351 +0,0 @@
# Validate IP addresses
let "ip_addresses" "dedup(winnow([ env.remote_ip ] + header.received[*].rcvd.ip + header.received[*].rcvd.from.ip + header.received[*].rcvd.by.ip))";
let "ip_addresses_len" "count(ip_addresses)";
let "i" "0";
while "i < ip_addresses_len" {
let "ip_address" "ip_addresses[i]";
let "is_from_addr" "i == 0";
let "i" "i + 1";
if eval "ip_address == '127.0.0.1' || ip_address == '::1'" {
continue;
}
# Do not check more than 10 IP addresses
if eval "i >= 10" {
break;
}
let "ip_reverse" "ip_reverse_name(ip_address)";
let "is_ip_v4" "len(ip_reverse) <= 15";
# Query SPAMHAUS
let "result" "rsplit_once(dns_query(ip_reverse + '.zen.spamhaus.org', 'ipv4')[0], '.')";
if eval "result[0] == '127.0.0'" {
let "result" "result[1]";
if eval "result == 2" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_SBL" "1";
} else {
let "t.RECEIVED_SPAMHAUS_SBL" "1";
}
} elsif eval "result == 3" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_CSS" "1";
} else {
let "t.RECEIVED_SPAMHAUS_CSS" "1";
}
} elsif eval "result >= 4 && result <= 7" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_XBL" "1";
} else {
let "t.RECEIVED_SPAMHAUS_XBL" "1";
}
} elsif eval "result == 9" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_DROP" "1";
} else {
let "t.RECEIVED_SPAMHAUS_PBL" "1";
}
} elsif eval "result == 10 || result == 11" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_PBL" "1";
} else {
let "t.RECEIVED_SPAMHAUS_PBL" "1";
}
} elsif eval "result == 254" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_BLOCKED_OPENRESOLVER" "1";
} else {
let "t.RECEIVED_SPAMHAUS_BLOCKED_OPENRESOLVER" "1";
}
} elsif eval "result == 255" {
if eval "is_from_addr" {
let "t.RBL_SPAMHAUS_BLOCKED" "1";
} else {
let "t.RECEIVED_SPAMHAUS_BLOCKED" "1";
}
} else {
# Unrecognized result
let "t.RBL_SPAMHAUS" "1";
}
}
if eval "is_from_addr" {
# Query IP reputation at Mailspike
let "result" "rsplit_once(dns_query(ip_reverse + '.rep.mailspike.net', 'ipv4')[0], '.')";
if eval "result[0] == '127.0.0'" {
let "result" "result[1]";
if eval "result == 10" {
let "t.RBL_MAILSPIKE_WORST" "1";
} elsif eval "result == 11" {
let "t.RBL_MAILSPIKE_VERYBAD" "1";
} elsif eval "result == 12" {
let "t.RBL_MAILSPIKE_BAD" "1";
} elsif eval "result >= 13 && result <= 16" {
let "t.RWL_MAILSPIKE_NEUTRAL" "1";
} elsif eval "result == 17" {
let "t.RWL_MAILSPIKE_POSSIBLE" "1";
} elsif eval "result == 18" {
let "t.RWL_MAILSPIKE_GOOD" "1";
} elsif eval "result == 19" {
let "t.RWL_MAILSPIKE_VERYGOOD" "1";
} elsif eval "result == 20" {
let "t.RWL_MAILSPIKE_EXCELLENT" "1";
}
}
# Query SenderScore
if eval "dns_exists(ip_reverse + '.bl.score.senderscore.com', 'ipv4')" {
let "t.RBL_SENDERSCORE" "1";
}
# Query SpamEatingMonkey
if eval "is_ip_v4 && dns_exists(ip_reverse + '.bl.spameatingmonkey.net', 'ipv4')" {
let "t.RBL_SEM" "1";
} elsif eval "!is_ip_v4 && dns_exists(ip_reverse + '.bl.ipv6.spameatingmonkey.net', 'ipv4')" {
let "t.RBL_SEM_IPV6" "1";
}
# Query VirusFree
if eval "dns_query(ip_reverse + '.bip.virusfree.cz', 'ipv4')[0] == '127.0.0.2'" {
let "t.RBL_VIRUSFREE_BOTNET" "1";
}
# Query NiX
if eval "dns_exists(ip_reverse + '.ix.dnsbl.manitu.net', 'ipv4')" {
let "t.RBL_NIXSPAM" "1";
}
# Query Spamcop
if eval "dns_exists(ip_reverse + '.bl.spamcop.net', 'ipv4')" {
let "t.RBL_SPAMCOP" "1";
}
# Query Barracuda
if eval "dns_exists(ip_reverse + '.b.barracudacentral.org', 'ipv4')" {
let "t.RBL_BARRACUDA" "1";
}
}
# Query Blocklist.de
if eval "dns_exists(ip_reverse + '.bl.blocklist.de', 'ipv4')" {
if eval "is_from_addr" {
let "t.RBL_BLOCKLISTDE" "1";
} else {
let "t.RECEIVED_BLOCKLISTDE" "1";
}
}
# Query DNSWL
let "result" "rsplit_once(dns_query(ip_reverse + '.list.dnswl.org', 'ipv4')[0], '.')";
if eval "starts_with(result[0], '127.')" {
let "result" "result[1]";
if eval "result == 0" {
let "t.RCVD_IN_DNSWL_NONE" "1";
} elsif eval "result == 1" {
let "t.RCVD_IN_DNSWL_LOW" "1";
} elsif eval "result == 2" {
let "t.RCVD_IN_DNSWL_MED" "1";
} elsif eval "result == 3" {
let "t.RCVD_IN_DNSWL_HI" "1";
} elsif eval "result == 255" {
let "t.DNSWL_BLOCKED" "1";
}
}
}
# Validate domain names
let "emails" "dedup(winnow(to_lowercase([from_addr, rto_addr, envelope.from] + tokenize(text_body, 'email'))))";
let "emails_len" "count(emails)";
let "domains" "dedup(winnow(to_lowercase([ env.helo_domain, env.iprev.ptr ] + email_part(emails, 'domain') + puny_decode(uri_part(urls, 'host')))))";
let "domains_len" "count(domains)";
let "i" "0";
while "i < domains_len" {
let "domain" "domains[i]";
let "i" "i + 1";
# Skip invalid and local domain names
if eval "!contains(domain, '.') ||
is_ip_addr(domain) ||
is_local_domain(DOMAIN_DIRECTORY, domain_part(domain, 'sld')) ||
key_exists('spam-allow', domain)" {
continue;
}
# Do not check more than 10 domain names
if eval "i >= 10" {
break;
}
# Query SpamHaus DBL
let "result" "rsplit_once(dns_query(domain + '.dbl.spamhaus.org', 'ipv4')[0], '.')";
if eval "result[0] == '127.0.1'" {
let "result" "result[1]";
if eval "result == 2" {
let "t.DBL_SPAM" "1";
} elsif eval "result == 4" {
let "t.DBL_PHISH" "1";
} elsif eval "result == 5" {
let "t.DBL_MALWARE" "1";
} elsif eval "result == 6" {
let "t.DBL_BOTNET" "1";
} elsif eval "result == 102" {
let "t.DBL_ABUSE" "1";
} elsif eval "result == 103" {
let "t.DBL_ABUSE_REDIR" "1";
} elsif eval "result == 104" {
let "t.DBL_ABUSE_PHISH" "1";
} elsif eval "result == 105" {
let "t.DBL_ABUSE_MALWARE" "1";
} elsif eval "result == 106" {
let "t.DBL_ABUSE_BOTNET" "1";
} elsif eval "result == 254" {
let "t.DBL_BLOCKED_OPENRESOLVER" "1";
} elsif eval "result == 255" {
let "t.DBL_BLOCKED" "1";
}
}
# Query SURBL multi
let "result" "rsplit_once(dns_query(domain + '.multi.surbl.org', 'ipv4')[0], '.')";
if eval "result[0] == '127.0.0'" {
let "result" "result[1]";
if eval "result == 128" {
let "t.CRACKED_SURBL" "1";
} elsif eval "result == 64" {
let "t.ABUSE_SURBL" "1";
} elsif eval "result == 16" {
let "t.MW_SURBL_MULTI" "1";
} elsif eval "result == 8" {
let "t.PH_SURBL_MULTI" "1";
} elsif eval "result == 1" {
let "t.SURBL_BLOCKED" "1";
}
}
# Query URIBL multi
let "result" "rsplit_once(dns_query(domain + '.multi.uribl.com', 'ipv4')[0], '.')";
if eval "result[0] == '127.0.0'" {
let "result" "result[1]";
if eval "result == 1" {
let "t.URIBL_BLOCKED" "1";
} elsif eval "result == 2" {
let "t.URIBL_BLACK" "1";
} elsif eval "result == 4" {
let "t.URIBL_GREY" "1";
} elsif eval "result == 8" {
let "t.URIBL_RED" "1";
}
}
# Query SpamEatingMonkey URIBL
if eval "dns_query(domain + '.uribl.spameatingmonkey.net', 'ipv4')[0] == '127.0.0.2'" {
let "t.SEM_URIBL" "1";
}
# Query SpamEatingMonkey FRESH15
if eval "dns_query(domain + '.fresh15.spameatingmonkey.net', 'ipv4')[0] == '127.0.0.2'" {
let "t.SEM_URIBL_FRESH15" "1";
}
}
# Check DKIM domains that passed validation
let "i" "count(env.dkim.domains)";
while "i > 0" {
let "i" "i - 1";
# Query DNSWL
let "result" "rsplit_once(dns_query(env.dkim.domains[i] + '.dwl.dnswl.org', 'ipv4')[0], '.')";
if eval "starts_with(result[0], '127.')" {
let "result" "result[1]";
if eval "result == 0" {
let "t.DWL_DNSWL_NONE" "1";
} elsif eval "result == 1" {
let "t.DWL_DNSWL_LOW" "1";
} elsif eval "result == 2" {
let "t.DWL_DNSWL_MED" "1";
} elsif eval "result == 3" {
let "t.DWL_DNSWL_HI" "1";
} elsif eval "result == 255" {
let "t.DWL_DNSWL_BLOCKED" "1";
}
}
}
# Validate email addresses
let "i" "0";
while "i < emails_len" {
let "email" "emails[i]";
let "i" "i + 1";
# Skip invalid and local e-mail addresses
if eval "!contains(email, '@') || is_local_domain(DOMAIN_DIRECTORY, domain_part(email_part(email, 'domain'), 'sld'))" {
continue;
}
# Do not check more than 10 email addresses
if eval "i >= 10" {
break;
}
# Query MSBL EBL
let "result" "rsplit_once(dns_query(hash(email, 'sha1') + '.ebl.msbl.org', 'ipv4')[0], '.')";
if eval "result[1] == 2 || result[1] == 3" {
if eval "result[0] == '127.0.0'" {
let "t.MSBL_EBL" "1";
} elsif eval "result[0] == '127.0.1'" {
let "t.MSBL_EBL_GREY" "1";
}
}
}
# Validate URL hashes
let "i" "0";
let "urls_len" "count(urls)";
while "i < urls_len" {
let "url" "urls[i]";
let "i" "i + 1";
# Do not check more than 10 URLs
if eval "i >= 10" {
break;
}
# Skip URLs pointing to local or trusted domains
let "domain" "domain_part(uri_part(url, 'host'), 'sld')";
if eval "is_local_domain(DOMAIN_DIRECTORY, domain) ||
key_exists('spam-allow', domain)" {
continue;
}
# Query SURBL HASHBL
let "result" "rsplit_once(dns_query(hash(url, 'md5') + '.hashbl.surbl.org', 'ipv4')[0], '.')";
if eval "starts_with(result[0], '127.0.')" {
let "result" "result[1]";
if eval "result == 8" {
let "t.SURBL_HASHBL_PHISH" "1";
} elsif eval "result == 16" {
let "t.SURBL_HASHBL_MALWARE" "1";
} elsif eval "result == 64" {
let "t.SURBL_HASHBL_ABUSE" "1";
} elsif eval "result == 128" {
let "t.SURBL_HASHBL_CRACKED" "1";
} elsif eval "result[0] == '127.0.1'" {
let "t.SURBL_HASHBL_EMAIL" "1";
}
}
}