Port Spam filter to Rust - part 4
This commit is contained in:
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user