From 7824368cf3395dce9b607c9979521dd685f3fc52 Mon Sep 17 00:00:00 2001 From: mdecimus Date: Sun, 1 Oct 2023 19:37:55 +0200 Subject: [PATCH] Added MIME, URL and headers spam modules. --- Cargo.lock | 109 +- crates/smtp/Cargo.toml | 3 + crates/smtp/src/outbound/delivery.rs | 9 + crates/smtp/src/scripts/functions/html.rs | 131 +- crates/smtp/src/scripts/functions/mod.rs | 17 +- crates/smtp/src/scripts/functions/text.rs | 87 +- crates/smtp/src/scripts/functions/unicode.rs | 134 + crates/smtp/src/scripts/functions/url.rs | 134 + crates/smtp/src/scripts/plugins/dns.rs | 182 + crates/smtp/src/scripts/plugins/http.rs | 70 + crates/smtp/src/scripts/plugins/lookup.rs | 58 + crates/smtp/src/scripts/plugins/mod.rs | 21 +- resources/config/lists/redirectors.inc | 6 +- resources/config/sieve/date.sieve | 2 +- resources/config/sieve/from.sieve | 8 +- resources/config/sieve/headers.sieve | 118 + resources/config/sieve/html.sieve | 113 +- resources/config/sieve/mime.sieve | 157 + resources/config/sieve/recipient.sieve | 69 +- resources/config/sieve/replyto.sieve | 7 +- resources/config/sieve/subject.sieve | 2 +- resources/config/sieve/url.sieve | 114 + resources/spamassassin/10_default_prefs.cf | 184 - resources/spamassassin/10_hasbase.cf | 89 - resources/spamassassin/20_advance_fee.cf | 96 - resources/spamassassin/20_aux_tlds.cf | 746 -- resources/spamassassin/20_body_tests.cf | 169 - resources/spamassassin/20_compensate.cf | 48 - resources/spamassassin/20_dnsbl_tests.cf | 251 - resources/spamassassin/20_drugs.cf | 277 - resources/spamassassin/20_dynrdns.cf | 213 - resources/spamassassin/20_fake_helo_tests.cf | 160 - resources/spamassassin/20_freemail.cf | 65 - resources/spamassassin/20_freemail_domains.cf | 545 - .../20_freemail_mailcom_domains.cf | 60 - resources/spamassassin/20_head_tests.cf | 614 -- resources/spamassassin/20_html_tests.cf | 239 - resources/spamassassin/20_imageinfo.cf | 111 - resources/spamassassin/20_mailspike.cf | 82 - resources/spamassassin/20_meta_tests.cf | 79 - resources/spamassassin/20_net_tests.cf | 49 - resources/spamassassin/20_pdfinfo.cf | 315 - resources/spamassassin/20_phrases.cf | 192 - resources/spamassassin/20_porn.cf | 45 - resources/spamassassin/20_ratware.cf | 327 - resources/spamassassin/20_uri_tests.cf | 123 - resources/spamassassin/20_vbounce.cf | 338 - resources/spamassassin/23_bayes.cf | 83 - resources/spamassassin/25_accessdb.cf | 36 - resources/spamassassin/25_antivirus.cf | 36 - resources/spamassassin/25_asn.cf | 45 - resources/spamassassin/25_dcc.cf | 80 - resources/spamassassin/25_dkim.cf | 147 - resources/spamassassin/25_dmarc.cf | 62 - resources/spamassassin/25_dnswl.cf | 70 - resources/spamassassin/25_pyzor.cf | 40 - resources/spamassassin/25_razor2.cf | 72 - resources/spamassassin/25_replace.cf | 210 - resources/spamassassin/25_spf.cf | 124 - resources/spamassassin/25_textcat.cf | 43 - resources/spamassassin/25_uribl.cf | 364 - resources/spamassassin/25_url_shortener.cf | 302 - resources/spamassassin/30_text_de.cf | 384 - resources/spamassassin/30_text_fr.cf | 283 - resources/spamassassin/30_text_it.cf | 35 - resources/spamassassin/30_text_nl.cf | 275 - resources/spamassassin/30_text_pl.cf | 267 - resources/spamassassin/30_text_pt_br.cf | 609 -- resources/spamassassin/50_scores.cf | 1014 -- .../spamassassin/60_adsp_override_dkim.cf | 218 - resources/spamassassin/60_awl.cf | 37 - resources/spamassassin/60_bayes_stopwords.cf | 69 - resources/spamassassin/60_shortcircuit.cf | 57 - resources/spamassassin/60_txrep.cf | 31 - resources/spamassassin/60_welcomelist.cf | 263 - resources/spamassassin/60_welcomelist_auth.cf | 1996 ---- resources/spamassassin/60_welcomelist_dkim.cf | 323 - resources/spamassassin/60_welcomelist_spf.cf | 170 - .../spamassassin/60_welcomelist_subject.cf | 87 - resources/spamassassin/72_active.cf | 9710 ----------------- resources/spamassassin/72_scores.cf | 407 - .../spamassassin/73_sandbox_manual_scores.cf | 121 - ...Mail-SpamAssassin-rules-4.0.0.r1905950.tgz | Bin 355737 -> 0 bytes .../STATISTICS-set0-72_scores.cf.txt | 40 - .../STATISTICS-set1-72_scores.cf.txt | 40 - .../STATISTICS-set2-72_scores.cf.txt | 0 .../STATISTICS-set3-72_scores.cf.txt | 0 resources/spamassassin/languages | Bin 133600 -> 0 bytes resources/spamassassin/local.cf | 112 - resources/spamassassin/regression_tests.cf | 62 - resources/spamassassin/sa-update-pubkey.txt | 80 - resources/spamassassin/user_prefs.template | 43 - tests/resources/smtp/antispam/headers.test | 58 + tests/resources/smtp/antispam/html.test | 98 +- tests/resources/smtp/antispam/mime.test | 354 + tests/resources/smtp/antispam/recipient.test | 65 + tests/resources/smtp/antispam/url.test | 81 + tests/resources/smtp/lists/redirectors.txt | 8 + tests/src/smtp/inbound/antispam.rs | 97 +- 99 files changed, 2120 insertions(+), 24056 deletions(-) create mode 100644 crates/smtp/src/scripts/functions/unicode.rs create mode 100644 crates/smtp/src/scripts/functions/url.rs create mode 100644 crates/smtp/src/scripts/plugins/dns.rs create mode 100644 crates/smtp/src/scripts/plugins/http.rs create mode 100644 crates/smtp/src/scripts/plugins/lookup.rs create mode 100644 resources/config/sieve/headers.sieve create mode 100644 resources/config/sieve/mime.sieve create mode 100644 resources/config/sieve/url.sieve delete mode 100644 resources/spamassassin/10_default_prefs.cf delete mode 100644 resources/spamassassin/10_hasbase.cf delete mode 100644 resources/spamassassin/20_advance_fee.cf delete mode 100644 resources/spamassassin/20_aux_tlds.cf delete mode 100644 resources/spamassassin/20_body_tests.cf delete mode 100644 resources/spamassassin/20_compensate.cf delete mode 100644 resources/spamassassin/20_dnsbl_tests.cf delete mode 100644 resources/spamassassin/20_drugs.cf delete mode 100644 resources/spamassassin/20_dynrdns.cf delete mode 100644 resources/spamassassin/20_fake_helo_tests.cf delete mode 100644 resources/spamassassin/20_freemail.cf delete mode 100644 resources/spamassassin/20_freemail_domains.cf delete mode 100644 resources/spamassassin/20_freemail_mailcom_domains.cf delete mode 100644 resources/spamassassin/20_head_tests.cf delete mode 100644 resources/spamassassin/20_html_tests.cf delete mode 100644 resources/spamassassin/20_imageinfo.cf delete mode 100644 resources/spamassassin/20_mailspike.cf delete mode 100644 resources/spamassassin/20_meta_tests.cf delete mode 100644 resources/spamassassin/20_net_tests.cf delete mode 100644 resources/spamassassin/20_pdfinfo.cf delete mode 100644 resources/spamassassin/20_phrases.cf delete mode 100644 resources/spamassassin/20_porn.cf delete mode 100644 resources/spamassassin/20_ratware.cf delete mode 100644 resources/spamassassin/20_uri_tests.cf delete mode 100644 resources/spamassassin/20_vbounce.cf delete mode 100644 resources/spamassassin/23_bayes.cf delete mode 100644 resources/spamassassin/25_accessdb.cf delete mode 100644 resources/spamassassin/25_antivirus.cf delete mode 100644 resources/spamassassin/25_asn.cf delete mode 100644 resources/spamassassin/25_dcc.cf delete mode 100644 resources/spamassassin/25_dkim.cf delete mode 100644 resources/spamassassin/25_dmarc.cf delete mode 100644 resources/spamassassin/25_dnswl.cf delete mode 100644 resources/spamassassin/25_pyzor.cf delete mode 100644 resources/spamassassin/25_razor2.cf delete mode 100644 resources/spamassassin/25_replace.cf delete mode 100644 resources/spamassassin/25_spf.cf delete mode 100644 resources/spamassassin/25_textcat.cf delete mode 100644 resources/spamassassin/25_uribl.cf delete mode 100644 resources/spamassassin/25_url_shortener.cf delete mode 100644 resources/spamassassin/30_text_de.cf delete mode 100644 resources/spamassassin/30_text_fr.cf delete mode 100644 resources/spamassassin/30_text_it.cf delete mode 100644 resources/spamassassin/30_text_nl.cf delete mode 100644 resources/spamassassin/30_text_pl.cf delete mode 100644 resources/spamassassin/30_text_pt_br.cf delete mode 100644 resources/spamassassin/50_scores.cf delete mode 100644 resources/spamassassin/60_adsp_override_dkim.cf delete mode 100644 resources/spamassassin/60_awl.cf delete mode 100644 resources/spamassassin/60_bayes_stopwords.cf delete mode 100644 resources/spamassassin/60_shortcircuit.cf delete mode 100644 resources/spamassassin/60_txrep.cf delete mode 100644 resources/spamassassin/60_welcomelist.cf delete mode 100644 resources/spamassassin/60_welcomelist_auth.cf delete mode 100644 resources/spamassassin/60_welcomelist_dkim.cf delete mode 100644 resources/spamassassin/60_welcomelist_spf.cf delete mode 100644 resources/spamassassin/60_welcomelist_subject.cf delete mode 100644 resources/spamassassin/72_active.cf delete mode 100644 resources/spamassassin/72_scores.cf delete mode 100644 resources/spamassassin/73_sandbox_manual_scores.cf delete mode 100644 resources/spamassassin/Mail-SpamAssassin-rules-4.0.0.r1905950.tgz delete mode 100644 resources/spamassassin/STATISTICS-set0-72_scores.cf.txt delete mode 100644 resources/spamassassin/STATISTICS-set1-72_scores.cf.txt delete mode 100644 resources/spamassassin/STATISTICS-set2-72_scores.cf.txt delete mode 100644 resources/spamassassin/STATISTICS-set3-72_scores.cf.txt delete mode 100644 resources/spamassassin/languages delete mode 100644 resources/spamassassin/local.cf delete mode 100644 resources/spamassassin/regression_tests.cf delete mode 100644 resources/spamassassin/sa-update-pubkey.txt delete mode 100644 resources/spamassassin/user_prefs.template create mode 100644 tests/resources/smtp/antispam/headers.test create mode 100644 tests/resources/smtp/antispam/mime.test create mode 100644 tests/resources/smtp/antispam/url.test create mode 100644 tests/resources/smtp/lists/redirectors.txt diff --git a/Cargo.lock b/Cargo.lock index 1298d06d..876fbbcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -137,15 +137,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -804,9 +804,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.5" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824956d0dca8334758a5b7f7e50518d66ea319330cbceedcf76905c2f6ab30e3" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", @@ -814,9 +814,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.5" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122ec64120a49b4563ccaedcbea7818d069ed8e9aa6d829b82d8a4128936b2ab" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", @@ -1100,7 +1100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "lock_api", "once_cell", "parking_lot_core", @@ -1121,6 +1121,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "decancer" +version = "1.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080b09f6adad25c23d8c47c54e52e59b0dc09d079c4b23e0f147dac440359d0d" + [[package]] name = "der" version = "0.7.8" @@ -1470,9 +1476,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" dependencies = [ "errno-dragonfly", "libc", @@ -1924,9 +1930,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" dependencies = [ "ahash 0.8.3", "allocator-api2", @@ -1938,7 +1944,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.0", + "hashbrown 0.14.1", ] [[package]] @@ -2147,7 +2153,7 @@ dependencies = [ [[package]] name = "hyper-util" version = "0.0.0" -source = "git+https://github.com/hyperium/hyper-util#eacb82d00d27751f2d56a21ab03530db46c4cf41" +source = "git+https://github.com/hyperium/hyper-util#d97181a278d9c59f1d7f2713732e400440861216" dependencies = [ "bytes", "futures-channel", @@ -2268,12 +2274,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.1", ] [[package]] @@ -2389,7 +2395,7 @@ checksum = "93f0c1347cd3ac8d7c6e3a2dc33ac496d365cf09fc0831aa61111e1a6738983e" dependencies = [ "cedarwood", "fxhash", - "hashbrown 0.14.0", + "hashbrown 0.14.1", "lazy_static", "phf", "phf_codegen", @@ -2677,9 +2683,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" [[package]] name = "lock_api" @@ -2886,9 +2892,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memoffset" @@ -3398,7 +3404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.0", + "indexmap 2.0.2", ] [[package]] @@ -3870,13 +3876,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", + "regex-automata 0.3.9", "regex-syntax 0.7.5", ] @@ -3891,9 +3897,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", "memchr", @@ -4157,9 +4163,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531" dependencies = [ "bitflags 2.4.0", "errno", @@ -4539,9 +4545,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b" dependencies = [ "lazy_static", ] @@ -4561,7 +4567,7 @@ checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "sieve-rs" version = "0.3.1" -source = "git+https://github.com/stalwartlabs/sieve#63929ef8713b3592b74ec4a080c15da44f5cb5af" +source = "git+https://github.com/stalwartlabs/sieve#3039311edc66988223e0bc6029a23fb3f8931f94" dependencies = [ "ahash 0.8.3", "bincode", @@ -4625,11 +4631,13 @@ dependencies = [ "ahash 0.8.3", "blake3", "dashmap", + "decancer", "directory", "form_urlencoded", "http-body-util", "hyper 1.0.0-rc.4", "hyper-util", + "idna 0.4.0", "imagesize", "lazy_static", "linkify", @@ -4656,6 +4664,7 @@ dependencies = [ "tokio", "tokio-rustls", "tracing", + "unicode-security", "utils", "webpki-roots 0.25.2", "whatlang", @@ -4665,7 +4674,7 @@ dependencies = [ [[package]] name = "smtp-proto" version = "0.1.1" -source = "git+https://github.com/stalwartlabs/smtp-proto#d2f81940d9ad74c9c03cd4bf55e681e9d94d4fe4" +source = "git+https://github.com/stalwartlabs/smtp-proto#d5949da111db6d9299c6a8928bf77f3dce337a1d" [[package]] name = "snafu" @@ -4781,7 +4790,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.0.0", + "indexmap 2.0.2", "log", "memchr", "once_cell", @@ -5709,6 +5718,22 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-script" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d817255e1bed6dfd4ca47258685d14d2bdcfbc64fdc9e3819bd5848057b8ecc" + +[[package]] +name = "unicode-security" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef5756b3097992b934b06608c69f48448a0fbe804bb1e72b982f6d7983e9e63" +dependencies = [ + "unicode-normalization", + "unicode-script", +] + [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -5942,9 +5967,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" +checksum = "07ecc0cd7cac091bf682ec5efa18b1cff79d617b84181f38b3951dbe135f607f" dependencies = [ "ring", "untrusted", diff --git a/crates/smtp/Cargo.toml b/crates/smtp/Cargo.toml index 6c108543..bff08522 100644 --- a/crates/smtp/Cargo.toml +++ b/crates/smtp/Cargo.toml @@ -50,6 +50,9 @@ lazy_static = "1.4" whatlang = "0.16" imagesize = "0.12" linkify = "0.10" +idna = "0.4" +decancer = "1.6.1" +unicode-security = "0.1.0" [features] test_mode = [] diff --git a/crates/smtp/src/outbound/delivery.rs b/crates/smtp/src/outbound/delivery.rs index 0e493fb2..02d10ef4 100644 --- a/crates/smtp/src/outbound/delivery.rs +++ b/crates/smtp/src/outbound/delivery.rs @@ -694,6 +694,15 @@ impl DeliveryAttempt { .await { StartTlsResult::Success { smtp_client } => { + tracing::debug!( + parent: &span, + context = "tls", + event = "success", + mx = envelope.mx, + protocol = ?smtp_client.tls_connection().protocol_version(), + cipher = ?smtp_client.tls_connection().negotiated_cipher_suite(), + ); + // Verify DANE if let Some(dane_policy) = &dane_policy { if let Err(status) = dane_policy.verify( diff --git a/crates/smtp/src/scripts/functions/html.rs b/crates/smtp/src/scripts/functions/html.rs index a6d8c3d0..1399e448 100644 --- a/crates/smtp/src/scripts/functions/html.rs +++ b/crates/smtp/src/scripts/functions/html.rs @@ -21,7 +21,8 @@ * for more details. */ -use hyper::Uri; +use std::borrow::Cow; + use mail_parser::decoders::html::{add_html_token, html_to_text}; use sieve::{runtime::Variable, Context}; @@ -74,6 +75,15 @@ pub fn fn_html_attr_size<'x>( dimension.map(Variable::Integer).unwrap_or_default() } +pub fn fn_html_attrs<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + html_attr_tokens( + v[0].to_cow().as_ref(), + v[1].to_cow().as_ref(), + v[2].to_string_array(), + ) + .into() +} + pub fn fn_html_attr<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { get_attribute(v[0].to_cow().as_ref(), v[1].to_cow().as_ref()) .map(|s| Variable::String(s.to_string())) @@ -232,6 +242,102 @@ pub fn html_to_tokens(input: &str) -> Vec> { tags } +pub fn html_attr_tokens(input: &str, tag: &str, attrs: Vec>) -> Vec> { + let input = input.as_bytes(); + let mut iter = input.iter().enumerate().peekable(); + let mut tags = vec![]; + + while let Some((mut pos, &ch)) = iter.next() { + if ch == b'<' { + if !matches!(input.get(pos + 1..pos + 4), Some(b"!--")) { + let mut in_quote = false; + let mut last_ch_pos: usize = 0; + + while matches!(iter.peek(), Some((_, &ch)) if ch.is_ascii_whitespace()) { + pos += 1; + iter.next(); + } + + let found_tag = tag.is_empty() + || (matches!(input.get(pos + 1..pos + tag.len() + 1), Some(t) if t.eq_ignore_ascii_case(tag.as_bytes())) + && matches!(input.get(pos + tag.len() + 1), Some(ch) if ch.is_ascii_whitespace())); + + 'outer: while let Some((pos, &ch)) = iter.next() { + match ch { + b'>' if !in_quote => { + break; + } + b'"' => { + in_quote = !in_quote; + } + b'=' if found_tag + && !in_quote + && attrs.iter().any(|attr| matches!(input.get(last_ch_pos.saturating_sub(attr.len()) + 1..last_ch_pos + 1), Some(a) if a.eq_ignore_ascii_case(attr.as_bytes()))) + && matches!(input.get(last_ch_pos + 1), Some(ch) if ch.is_ascii_whitespace() || *ch == b'=') => + { + while matches!(iter.peek(), Some((_, &ch)) if ch.is_ascii_whitespace()) + { + iter.next(); + } + let mut tag = vec![]; + + for (_, &ch) in iter.by_ref() { + match ch { + b'>' if !in_quote => { + if !tag.is_empty() { + tags.push(Variable::String( + String::from_utf8(tag).unwrap_or_default(), + )); + } + break 'outer; + } + b'"' => { + if in_quote { + in_quote = false; + break; + } else { + in_quote = true; + } + } + b' ' | b'\t' | b'\r' | b'\n' if !in_quote => { + break; + } + _ => { + tag.push(ch); + } + } + } + + if !tag.is_empty() { + tags.push(Variable::String( + String::from_utf8(tag).unwrap_or_default(), + )); + } + } + b' ' | b'\t' | b'\r' | b'\n' => {} + _ => { + last_ch_pos = pos; + } + } + } + } else { + let mut last_ch: u8 = 0; + let mut before_last_ch: u8 = 0; + + for (_, &ch) in iter.by_ref() { + if ch == b'>' && last_ch == b'-' && before_last_ch == b'-' { + break; + } + before_last_ch = last_ch; + last_ch = ch; + } + } + } + } + + tags +} + pub fn html_img_area(arr: &[Variable<'_>]) -> u32 { arr.iter() .filter_map(|v| { @@ -261,29 +367,6 @@ pub fn html_img_area(arr: &[Variable<'_>]) -> u32 { .sum::() } -pub fn fn_uri_part<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { - v[0].to_cow() - .parse::() - .ok() - .and_then(|uri| match v[1].to_cow().as_ref() { - "scheme" => uri.scheme_str().map(|s| Variable::String(s.to_lowercase())), - "host" => uri.host().map(|s| Variable::String(s.to_lowercase())), - "scheme_host" => uri - .scheme_str() - .and_then(|s| (s, uri.host()?).into()) - .map(|(s, h)| Variable::String(format!("{}://{}", s, h))), - "path" => Variable::String(uri.path().to_string()).into(), - "port" => uri.port_u16().map(|port| Variable::Integer(port as i64)), - "query" => uri.query().map(|s| Variable::String(s.to_string())), - "path_query" => uri - .path_and_query() - .map(|s| Variable::String(s.to_string())), - "authority" => uri.authority().map(|s| Variable::String(s.to_string())), - _ => None, - }) - .unwrap_or_default() -} - pub fn get_attribute<'x>(tag: &'x str, attr_name: &str) -> Option<&'x str> { let tag = tag.as_bytes(); let attr_name = attr_name.as_bytes(); diff --git a/crates/smtp/src/scripts/functions/mod.rs b/crates/smtp/src/scripts/functions/mod.rs index 89bf5ccf..3d9d6708 100644 --- a/crates/smtp/src/scripts/functions/mod.rs +++ b/crates/smtp/src/scripts/functions/mod.rs @@ -28,12 +28,16 @@ pub mod html; mod image; mod misc; mod text; +mod unicode; +mod url; use sieve::{runtime::Variable, FunctionMap}; use crate::config::scripts::SieveContext; -use self::{array::*, email::*, header::*, html::*, image::*, misc::*, text::*}; +use self::{ + array::*, email::*, header::*, html::*, image::*, misc::*, text::*, unicode::*, url::*, +}; pub fn register_functions() -> FunctionMap { FunctionMap::new() @@ -52,6 +56,7 @@ pub fn register_functions() -> FunctionMap { .with_function("html_to_text", fn_html_to_text) .with_function("is_uppercase", fn_is_uppercase) .with_function("is_lowercase", fn_is_lowercase) + .with_function("has_digits", fn_has_digits) .with_function("tokenize_words", fn_tokenize_words) .with_function("tokenize_html", fn_tokenize_html) .with_function("max_line_len", fn_max_line_len) @@ -63,9 +68,15 @@ pub fn register_functions() -> FunctionMap { .with_function("lines", fn_lines) .with_function("is_header_utf8_valid", fn_is_header_utf8_valid) .with_function("img_metadata", fn_img_metadata) - .with_function("sort", fn_sort) .with_function("is_ip_addr", fn_is_ip_addr) .with_function("winnow", fn_winnow) + .with_function("has_zwsp", fn_has_zwsp) + .with_function("has_obscured", fn_has_obscured) + .with_function("is_single_script", fn_is_single_script) + .with_function("puny_decode", fn_puny_decode) + .with_function("unicode_skeleton", fn_unicode_skeleton) + .with_function("cure_text", fn_cure_text) + .with_function_args("sort", fn_sort, 2) .with_function_args("tokenize_url", fn_tokenize_url, 2) .with_function_args("email_part", fn_email_part, 2) .with_function_args("domain_part", fn_domain_part, 2) @@ -80,10 +91,12 @@ pub fn register_functions() -> FunctionMap { .with_function_args("levenshtein_distance", fn_levenshtein_distance, 2) .with_function_args("html_has_tag", fn_html_has_tag, 2) .with_function_args("html_attr", fn_html_attr, 2) + .with_function_args("html_attrs", fn_html_attrs, 3) .with_function_args("html_attr_size", fn_html_attr_size, 3) .with_function_args("uri_part", fn_uri_part, 2) .with_function_args("substring", fn_substring, 3) .with_function_args("split", fn_split, 2) + .with_function_args("rsplit", fn_rsplit, 2) .with_function_args("strip_prefix", fn_strip_prefix, 2) .with_function_args("strip_suffix", fn_strip_suffix, 2) .with_function_args("is_intersect", fn_is_intersect, 2) diff --git a/crates/smtp/src/scripts/functions/text.rs b/crates/smtp/src/scripts/functions/text.rs index 475e703a..947ad5cd 100644 --- a/crates/smtp/src/scripts/functions/text.rs +++ b/crates/smtp/src/scripts/functions/text.rs @@ -50,25 +50,6 @@ pub fn fn_len<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Var .into() } -pub fn fn_is_ascii<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { - match &v[0] { - Variable::String(s) => s.chars().all(|c| c.is_ascii()), - Variable::StringRef(s) => s.chars().all(|c| c.is_ascii()), - Variable::Integer(_) | Variable::Float(_) => true, - Variable::Array(a) => a.iter().all(|v| match v { - Variable::String(s) => s.chars().all(|c| c.is_ascii()), - Variable::StringRef(s) => s.chars().all(|c| c.is_ascii()), - _ => true, - }), - Variable::ArrayRef(a) => a.iter().all(|v| match v { - Variable::String(s) => s.chars().all(|c| c.is_ascii()), - Variable::StringRef(s) => s.chars().all(|c| c.is_ascii()), - _ => true, - }), - } - .into() -} - pub fn fn_to_lowercase<'x>( _: &'x Context<'x, SieveContext>, mut v: Vec>, @@ -129,6 +110,14 @@ pub fn fn_is_lowercase<'x>(_: &'x Context<'x, SieveContext>, v: Vec .into() } +pub fn fn_has_digits<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + v[0].to_cow() + .as_ref() + .chars() + .any(|c| c.is_ascii_digit()) + .into() +} + pub fn fn_tokenize_words<'x>( _: &'x Context<'x, SieveContext>, v: Vec>, @@ -305,52 +294,24 @@ pub fn fn_split<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> V } } -pub fn fn_tokenize_url<'x>( - ctx: &'x Context<'x, SieveContext>, - mut v: Vec>, -) -> Variable<'x> { - let must_have_scheme = v[1].to_bool(); - let filter_url = |url: &str| -> bool { - if must_have_scheme || url.contains("://") { - true - } else { - // Filter out possible URLs without a valid TLD - let url = url.split_once('/').map_or(url, |(f, _)| f); - let tld = url.rsplit_once('.').map_or(url, |(_, tld)| tld); - ctx.context().psl.contains(tld) - } - }; - - match v.remove(0) { - Variable::StringRef(text) => linkify::LinkFinder::new() - .url_must_have_scheme(must_have_scheme) - .links(text.as_ref()) - .filter_map(|url| { - let url = url.as_str(); - if filter_url(url) { - Some(Variable::from(url.to_string())) - } else { - None - } - }) +pub fn fn_rsplit<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + match &v[0] { + Variable::StringRef(s) => s + .rsplit(v[1].to_cow().as_ref()) + .map(Variable::from) + .collect::>() + .into(), + Variable::String(s) => s + .rsplit(v[1].to_cow().as_ref()) + .map(|s| Variable::String(s.to_string())) + .collect::>() + .into(), + val => val + .to_string() + .rsplit(v[1].to_cow().as_ref()) + .map(|s| Variable::String(s.to_string())) .collect::>() .into(), - v @ (Variable::String(_) | Variable::Array(_) | Variable::ArrayRef(_)) => { - linkify::LinkFinder::new() - .url_must_have_scheme(must_have_scheme) - .links(v.to_cow().as_ref()) - .filter_map(|url| { - let url = url.as_str(); - if filter_url(url) { - Some(Variable::from(url.to_string())) - } else { - None - } - }) - .collect::>() - .into() - } - v => v, } } diff --git a/crates/smtp/src/scripts/functions/unicode.rs b/crates/smtp/src/scripts/functions/unicode.rs new file mode 100644 index 00000000..21fbca67 --- /dev/null +++ b/crates/smtp/src/scripts/functions/unicode.rs @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Stalwart Labs Ltd. + * + * This file is part of Stalwart Mail Server. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * in the LICENSE file at the top-level directory of this distribution. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * You can be released from the requirements of the AGPLv3 license by + * purchasing a commercial license. Please contact licensing@stalw.art + * for more details. +*/ + +use sieve::{runtime::Variable, Context}; +use unicode_security::MixedScript; + +use crate::config::scripts::SieveContext; + +pub fn fn_is_ascii<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + match &v[0] { + Variable::String(s) => s.chars().all(|c| c.is_ascii()), + Variable::StringRef(s) => s.chars().all(|c| c.is_ascii()), + Variable::Integer(_) | Variable::Float(_) => true, + Variable::Array(a) => a.iter().all(|v| match v { + Variable::String(s) => s.chars().all(|c| c.is_ascii()), + Variable::StringRef(s) => s.chars().all(|c| c.is_ascii()), + _ => true, + }), + Variable::ArrayRef(a) => a.iter().all(|v| match v { + Variable::String(s) => s.chars().all(|c| c.is_ascii()), + Variable::StringRef(s) => s.chars().all(|c| c.is_ascii()), + _ => true, + }), + } + .into() +} + +pub fn fn_has_zwsp<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + match &v[0] { + Variable::String(s) => s.chars().any(|c| c.is_zwsp()), + Variable::StringRef(s) => s.chars().any(|c| c.is_zwsp()), + Variable::Array(a) => a.iter().any(|v| match v { + Variable::String(s) => s.chars().any(|c| c.is_zwsp()), + Variable::StringRef(s) => s.chars().any(|c| c.is_zwsp()), + _ => true, + }), + Variable::ArrayRef(a) => a.iter().any(|v| match v { + Variable::String(s) => s.chars().any(|c| c.is_zwsp()), + Variable::StringRef(s) => s.chars().any(|c| c.is_zwsp()), + _ => true, + }), + Variable::Integer(_) | Variable::Float(_) => false, + } + .into() +} + +pub fn fn_has_obscured<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + match &v[0] { + Variable::String(s) => s.chars().any(|c| c.is_obscured()), + Variable::StringRef(s) => s.chars().any(|c| c.is_obscured()), + Variable::Array(a) => a.iter().any(|v| match v { + Variable::String(s) => s.chars().any(|c| c.is_obscured()), + Variable::StringRef(s) => s.chars().any(|c| c.is_obscured()), + _ => true, + }), + Variable::ArrayRef(a) => a.iter().any(|v| match v { + Variable::String(s) => s.chars().any(|c| c.is_obscured()), + Variable::StringRef(s) => s.chars().any(|c| c.is_obscured()), + _ => true, + }), + Variable::Integer(_) | Variable::Float(_) => false, + } + .into() +} + +trait CharUtils { + fn is_zwsp(&self) -> bool; + fn is_obscured(&self) -> bool; +} + +impl CharUtils for char { + fn is_zwsp(&self) -> bool { + matches!( + self, + '\u{200B}' | '\u{200C}' | '\u{200D}' | '\u{FEFF}' | '\u{00AD}' + ) + } + + fn is_obscured(&self) -> bool { + matches!( + self, + '\u{200B}'..='\u{200F}' + | '\u{2028}'..='\u{202F}' + | '\u{205F}'..='\u{206F}' + | '\u{FEFF}' + ) + } +} + +pub fn fn_cure_text<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + decancer::cure(v[0].to_cow().as_ref()).into_str().into() +} + +pub fn fn_unicode_skeleton<'x>( + _: &'x Context<'x, SieveContext>, + v: Vec>, +) -> Variable<'x> { + unicode_security::skeleton(v[0].to_cow().as_ref()) + .collect::() + .into() +} + +pub fn fn_is_single_script<'x>( + _: &'x Context<'x, SieveContext>, + v: Vec>, +) -> Variable<'x> { + let text = v[0].to_cow(); + if !text.is_empty() { + text.as_ref().is_single_script() + } else { + true + } + .into() +} diff --git a/crates/smtp/src/scripts/functions/url.rs b/crates/smtp/src/scripts/functions/url.rs new file mode 100644 index 00000000..94c69763 --- /dev/null +++ b/crates/smtp/src/scripts/functions/url.rs @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Stalwart Labs Ltd. + * + * This file is part of Stalwart Mail Server. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * in the LICENSE file at the top-level directory of this distribution. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * You can be released from the requirements of the AGPLv3 license by + * purchasing a commercial license. Please contact licensing@stalw.art + * for more details. +*/ + +use std::net::IpAddr; + +use hyper::Uri; +use sieve::{runtime::Variable, Context}; + +use crate::config::scripts::SieveContext; + +pub fn fn_tokenize_url<'x>( + ctx: &'x Context<'x, SieveContext>, + mut v: Vec>, +) -> Variable<'x> { + let must_have_scheme = v[1].to_bool(); + + match v.remove(0) { + Variable::StringRef(text) => linkify::LinkFinder::new() + .url_must_have_scheme(must_have_scheme) + .links(text.as_ref()) + .filter_map(|url| filter_url(url.as_str(), must_have_scheme, ctx)) + .collect::>() + .into(), + v @ (Variable::String(_) | Variable::Array(_) | Variable::ArrayRef(_)) => { + linkify::LinkFinder::new() + .url_must_have_scheme(must_have_scheme) + .links(v.to_cow().as_ref()) + .filter_map(|url| { + filter_url(url.as_str(), must_have_scheme, ctx).map(|v| v.into_owned()) + }) + .collect::>() + .into() + } + v => v, + } +} + +fn filter_url<'x, 'y>( + url: &'x str, + must_have_scheme: bool, + ctx: &'y Context<'y, SieveContext>, +) -> Option> { + if must_have_scheme || url.contains("://") { + Some(Variable::StringRef(url)) + } else { + // Filter out possible URLs without a valid TLD + let host = url.split_once('/').map_or(url, |(f, _)| f); + if (host + .as_bytes() + .first() + .map_or(true, |ch| ch.is_ascii_hexdigit()) + && host.parse::().is_ok()) + || ctx + .context() + .psl + .contains(host.rsplit_once('.').map_or(host, |(_, tld)| tld)) + || host.ends_with(".onion") + { + Some(Variable::String(format!("https://{url}"))) + } else { + None + } + } +} + +pub fn fn_uri_part<'x>(_: &'x Context<'x, SieveContext>, v: Vec>) -> Variable<'x> { + v[0].to_cow() + .parse::() + .ok() + .and_then(|uri| match v[1].to_cow().as_ref() { + "scheme" => uri.scheme_str().map(|s| Variable::String(s.to_lowercase())), + "host" => uri.host().map(|s| Variable::String(s.to_lowercase())), + "scheme_host" => uri + .scheme_str() + .and_then(|s| (s, uri.host()?).into()) + .map(|(s, h)| Variable::String(format!("{}://{}", s, h))), + "path" => Variable::String(uri.path().to_string()).into(), + "port" => uri.port_u16().map(|port| Variable::Integer(port as i64)), + "query" => uri.query().map(|s| Variable::String(s.to_string())), + "path_query" => uri + .path_and_query() + .map(|s| Variable::String(s.to_string())), + "authority" => uri.authority().map(|s| Variable::String(s.to_string())), + _ => None, + }) + .unwrap_or_default() +} + +pub fn fn_puny_decode<'x>( + _: &'x Context<'x, SieveContext>, + mut v: Vec>, +) -> Variable<'x> { + let domain = v[0].to_cow(); + if domain.contains("xn--") { + let mut decoded = String::with_capacity(domain.len()); + for part in domain.split('.') { + if !decoded.is_empty() { + decoded.push('.'); + } + + if let Some(puny) = part + .strip_prefix("xn--") + .and_then(idna::punycode::decode_to_string) + { + decoded.push_str(&puny); + } else { + decoded.push_str(part); + } + } + decoded.into() + } else { + v.remove(0) + } +} diff --git a/crates/smtp/src/scripts/plugins/dns.rs b/crates/smtp/src/scripts/plugins/dns.rs new file mode 100644 index 00000000..057189d1 --- /dev/null +++ b/crates/smtp/src/scripts/plugins/dns.rs @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2023 Stalwart Labs Ltd. + * + * This file is part of Stalwart Mail Server. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * in the LICENSE file at the top-level directory of this distribution. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * You can be released from the requirements of the AGPLv3 license by + * purchasing a commercial license. Please contact licensing@stalw.art + * for more details. +*/ + +use std::net::IpAddr; + +use mail_auth::IpLookupStrategy; +use sieve::{runtime::Variable, FunctionMap}; + +use crate::config::scripts::SieveContext; + +use super::PluginContext; + +pub fn register(plugin_id: u32, fnc_map: &mut FunctionMap) { + fnc_map.set_external_function("dns_query", plugin_id, 2); +} + +pub fn register_exists(plugin_id: u32, fnc_map: &mut FunctionMap) { + fnc_map.set_external_function("dns_exists", plugin_id, 2); +} + +pub fn exec(ctx: PluginContext<'_>) -> Variable<'static> { + let entry = ctx.arguments[0].to_cow(); + let record_type = ctx.arguments[1].to_cow(); + + if record_type.eq_ignore_ascii_case("ip") { + match ctx.handle.block_on(ctx.core.resolvers.dns.ip_lookup( + entry.as_ref(), + IpLookupStrategy::Ipv4thenIpv6, + 10, + )) { + Ok(result) => result + .iter() + .map(|ip| Variable::String(ip.to_string())) + .collect::>() + .into(), + Err(err) => err.short_error().into(), + } + } else if record_type.eq_ignore_ascii_case("mx") { + match ctx + .handle + .block_on(ctx.core.resolvers.dns.mx_lookup(entry.as_ref())) + { + Ok(result) => result + .iter() + .flat_map(|mx| { + mx.exchanges + .iter() + .map(|host| Variable::String(format!("{} {}", mx.preference, host))) + }) + .collect::>() + .into(), + Err(err) => err.short_error().into(), + } + } else if record_type.eq_ignore_ascii_case("ptr") { + if let Ok(addr) = entry.parse::() { + match ctx.handle.block_on(ctx.core.resolvers.dns.ptr_lookup(addr)) { + Ok(result) => result + .iter() + .map(|host| Variable::String(host.to_string())) + .collect::>() + .into(), + Err(err) => err.short_error().into(), + } + } else { + Variable::default() + } + } else if record_type.eq_ignore_ascii_case("ipv4") { + match ctx + .handle + .block_on(ctx.core.resolvers.dns.ipv4_lookup(entry.as_ref())) + { + Ok(result) => result + .iter() + .map(|ip| Variable::String(ip.to_string())) + .collect::>() + .into(), + Err(err) => err.short_error().into(), + } + } else if record_type.eq_ignore_ascii_case("ipv6") { + match ctx + .handle + .block_on(ctx.core.resolvers.dns.ipv6_lookup(entry.as_ref())) + { + Ok(result) => result + .iter() + .map(|ip| Variable::String(ip.to_string())) + .collect::>() + .into(), + Err(err) => err.short_error().into(), + } + } else { + Variable::default() + } +} + +pub fn exec_exists(ctx: PluginContext<'_>) -> Variable<'static> { + let entry = ctx.arguments[0].to_cow(); + let record_type = ctx.arguments[1].to_cow(); + + if record_type.eq_ignore_ascii_case("ip") { + match ctx.handle.block_on(ctx.core.resolvers.dns.ip_lookup( + entry.as_ref(), + IpLookupStrategy::Ipv4thenIpv6, + 10, + )) { + Ok(result) => !result.is_empty(), + Err(_) => false, + } + } else if record_type.eq_ignore_ascii_case("mx") { + match ctx + .handle + .block_on(ctx.core.resolvers.dns.mx_lookup(entry.as_ref())) + { + Ok(result) => result.iter().any(|mx| !mx.exchanges.is_empty()), + Err(_) => false, + } + } else if record_type.eq_ignore_ascii_case("ptr") { + if let Ok(addr) = entry.parse::() { + match ctx.handle.block_on(ctx.core.resolvers.dns.ptr_lookup(addr)) { + Ok(result) => !result.is_empty(), + Err(_) => false, + } + } else { + false + } + } else if record_type.eq_ignore_ascii_case("ipv4") { + match ctx + .handle + .block_on(ctx.core.resolvers.dns.ipv4_lookup(entry.as_ref())) + { + Ok(result) => !result.is_empty(), + Err(_) => false, + } + } else if record_type.eq_ignore_ascii_case("ipv6") { + match ctx + .handle + .block_on(ctx.core.resolvers.dns.ipv6_lookup(entry.as_ref())) + { + Ok(result) => !result.is_empty(), + Err(_) => false, + } + } else { + false + } + .into() +} + +trait ShortError { + fn short_error(&self) -> &'static str; +} + +impl ShortError for mail_auth::Error { + fn short_error(&self) -> &'static str { + match self { + mail_auth::Error::DnsError(_) => "temp_fail", + mail_auth::Error::DnsRecordNotFound(_) => "not_found", + mail_auth::Error::Io(_) => "io_error", + mail_auth::Error::InvalidRecordType => "invalid_record", + _ => "unknown_error", + } + } +} diff --git a/crates/smtp/src/scripts/plugins/http.rs b/crates/smtp/src/scripts/plugins/http.rs new file mode 100644 index 00000000..54ecb4b5 --- /dev/null +++ b/crates/smtp/src/scripts/plugins/http.rs @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Stalwart Labs Ltd. + * + * This file is part of Stalwart Mail Server. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * in the LICENSE file at the top-level directory of this distribution. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * You can be released from the requirements of the AGPLv3 license by + * purchasing a commercial license. Please contact licensing@stalw.art + * for more details. +*/ + +use std::time::Duration; + +use reqwest::redirect::Policy; +use sieve::{runtime::Variable, FunctionMap}; + +use crate::config::scripts::SieveContext; + +use super::PluginContext; + +pub fn register_header(plugin_id: u32, fnc_map: &mut FunctionMap) { + fnc_map.set_external_function("http_header", plugin_id, 4); +} + +pub fn exec_header(ctx: PluginContext<'_>) -> Variable<'static> { + let url = ctx.arguments[0].to_cow(); + let header = ctx.arguments[1].to_cow(); + let agent = ctx.arguments[2].to_cow(); + let timeout = ctx.arguments[3].to_cow().parse::().unwrap_or(5000); + + #[cfg(feature = "test_mode")] + if url.contains("redirect.") { + return Variable::String(url.split_once("/?").unwrap().1.to_string()); + } + + if let Ok(client) = reqwest::Client::builder() + .user_agent(agent.as_ref()) + .timeout(Duration::from_millis(timeout)) + .redirect(Policy::none()) + .danger_accept_invalid_certs(true) + .build() + { + let _enter = ctx.handle.enter(); + ctx.handle + .block_on(client.get(url.as_ref()).send()) + .ok() + .and_then(|response| { + response + .headers() + .get(header.as_ref()) + .and_then(|h| h.to_str().ok()) + .map(|h| Variable::String(h.to_string())) + }) + .unwrap_or_default() + } else { + false.into() + } +} diff --git a/crates/smtp/src/scripts/plugins/lookup.rs b/crates/smtp/src/scripts/plugins/lookup.rs new file mode 100644 index 00000000..af8eb23d --- /dev/null +++ b/crates/smtp/src/scripts/plugins/lookup.rs @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023 Stalwart Labs Ltd. + * + * This file is part of Stalwart Mail Server. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * in the LICENSE file at the top-level directory of this distribution. + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * You can be released from the requirements of the AGPLv3 license by + * purchasing a commercial license. Please contact licensing@stalw.art + * for more details. +*/ + +use sieve::{runtime::Variable, FunctionMap}; + +use crate::config::scripts::SieveContext; + +use super::PluginContext; + +pub fn register(plugin_id: u32, fnc_map: &mut FunctionMap) { + fnc_map.set_external_function("lookup", plugin_id, 2); +} + +pub fn exec(ctx: PluginContext<'_>) -> Variable<'static> { + let lookup_id = ctx.arguments[0].to_cow(); + let item = ctx.arguments[1].to_cow(); + let span = ctx.span; + + if !lookup_id.is_empty() && !item.is_empty() { + if let Some(lookup) = ctx.core.sieve.lookup.get(lookup_id.as_ref()) { + return ctx + .handle + .block_on(lookup.contains(item.as_ref())) + .unwrap_or(false) + .into(); + } else { + tracing::warn!( + parent: span, + context = "sieve:lookup", + event = "failed", + reason = "Unknown lookup id", + lookup_id = %lookup_id, + ); + } + } + + false.into() +} diff --git a/crates/smtp/src/scripts/plugins/mod.rs b/crates/smtp/src/scripts/plugins/mod.rs index ad5099e4..0ccb2171 100644 --- a/crates/smtp/src/scripts/plugins/mod.rs +++ b/crates/smtp/src/scripts/plugins/mod.rs @@ -21,7 +21,10 @@ * for more details. */ +pub mod dns; pub mod exec; +pub mod http; +pub mod lookup; pub mod query; use ahash::AHashMap; @@ -43,8 +46,22 @@ pub struct PluginContext<'x> { pub arguments: Vec>, } -const PLUGINS_EXEC: [ExecPluginFnc; 2] = [query::exec, exec::exec]; -const PLUGINS_REGISTER: [RegisterPluginFnc; 2] = [query::register, exec::register]; +const PLUGINS_EXEC: [ExecPluginFnc; 6] = [ + query::exec, + exec::exec, + lookup::exec, + dns::exec, + dns::exec_exists, + http::exec_header, +]; +const PLUGINS_REGISTER: [RegisterPluginFnc; 6] = [ + query::register, + exec::register, + lookup::register, + dns::register, + dns::register_exists, + http::register_header, +]; pub trait RegisterSievePlugins { fn register_plugins(self) -> Self; diff --git a/resources/config/lists/redirectors.inc b/resources/config/lists/redirectors.inc index e976280b..d3e9d22b 100644 --- a/resources/config/lists/redirectors.inc +++ b/resources/config/lists/redirectors.inc @@ -1015,9 +1015,9 @@ wurl.in wurl.us wuw.su ww.tl -www.clickmeeting.com -www.grandstreamnetworks.ru -www.reg.ru +clickmeeting.com +grandstreamnetworks.ru +reg.ru wz.ae x2t.com xaa.su diff --git a/resources/config/sieve/date.sieve b/resources/config/sieve/date.sieve index 99057fc6..cf02dda3 100644 --- a/resources/config/sieve/date.sieve +++ b/resources/config/sieve/date.sieve @@ -1,4 +1,4 @@ -if eval "!is_empty(header.date.raw)" { +if eval "header.date.exists" { let "date" "header.date.date"; if eval "date != 0" { diff --git a/resources/config/sieve/from.sieve b/resources/config/sieve/from.sieve index baab379d..93f624ef 100644 --- a/resources/config/sieve/from.sieve +++ b/resources/config/sieve/from.sieve @@ -21,9 +21,9 @@ if eval "from_count > 0" { let "t.WWW_DOT_DOMAIN" "1"; } - if string :list "${from_domain_sld}" "spam/free-domains" { + if eval "lookup('spam/free-domains', from_domain_sld)" { let "t.FREEMAIL_FROM" "1"; - } elsif string :list "${from_domain_sld}" "spam/disposable-domains" { + } elsif eval "lookup('spam/disposable-domains', from_domain_sld)" { let "t.DISPOSABLE_FROM" "1"; } } else { @@ -132,9 +132,9 @@ if eval "!is_empty(envelope.from)" { let "envfrom_domain_sld" "domain_part(email_part(envelope.from, 'domain'), 'sld')"; if eval "!is_empty(envfrom_domain_sld)" { - if string :list "${envfrom_domain_sld}" "spam/free-domains" { + if eval "lookup('spam/free-domains', envfrom_domain_sld)" { let "t.FREEMAIL_ENVFROM" "1"; - } elsif string :list "${envfrom_domain_sld}" "spam/disposable-domains" { + } elsif eval "lookup('spam/disposable-domains', envfrom_domain_sld)" { let "t.DISPOSABLE_ENVFROM" "1"; } } diff --git a/resources/config/sieve/headers.sieve b/resources/config/sieve/headers.sieve new file mode 100644 index 00000000..f0f67e3e --- /dev/null +++ b/resources/config/sieve/headers.sieve @@ -0,0 +1,118 @@ + + +if eval "header.x-priority.exists" { + let "xp" "header.x-priority"; + if eval "xp == 0" { + let "t.HAS_X_PRIO_ZERO" "1"; + } elsif eval "xp == 1" { + let "t.HAS_X_PRIO_ONE" "1"; + } elsif eval "xp == 2" { + let "t.HAS_X_PRIO_TWO" "1"; + } elsif eval "xp <= 4" { + let "t.HAS_X_PRIO_THREE" "1"; + } elsif eval "xp >= 5" { + let "t.HAS_X_PRIO_FIVE" "1"; + } +} + +let "unique_header_names" "to_lowercase(header.Content-Type:Content-Transfer-Encoding:Date:From:Sender:Reply-To:To:Cc:Bcc:Message-ID:In-Reply-To:References:Subject[*].raw_name)"; +if eval "count(unique_header_names) != count(dedup(unique_header_names))" { + let "t.MULTIPLE_UNIQUE_HEADERS" "1"; +} + +# Wrong case X-Mailer +if eval "header.x-mailer.exists && header.x-mailer.raw_name != 'X-Mailer'" { + let "t.XM_CASE" "1"; +} + +# Has organization header +if eval "header.organization:organisation.exists" { + let "t.HAS_ORG_HEADER" "1"; +} + +# Has X-Originating-IP header +if eval "header.X-Originating-IP.exists" { + let "t.HAS_XOIP" "1"; +} + +# Has List-Unsubscribe header +if eval "header.List-Unsubscribe.exists" { + let "t.HAS_LIST_UNSUB" "1"; +} + +# Missing version number in X-Mailer or User-Agent headers +if eval "(header.X-Mailer.exists && !has_digits(header.X-Mailer)) || (header.User-Agent.exists && !has_digits(header.User-Agent))" { + let "t.XM_UA_NO_VERSION" "1"; +} + +# Precedence is bulk +if eval "eq_ignore_case(header.Precedence, 'bulk')" { + let "t.PRECEDENCE_BULK" "1"; +} + +# Upstream SPAM filtering +if eval "contains_ignore_case(header.X-KLMS-AntiSpam-Status, 'spam')" { + # Kaspersky Security for Mail Server says this message is spam + let "t.KLMS_SPAM" "1"; +} +let "spam_hdr" "to_lowercase(header.X-Spam:X-Spam-Flag:X-Spam-Status)"; +if eval "contains(spam_hdr, 'yes') || contains(spam_hdr, 'true') || contains(spam_hdr, 'spam')" { + # Message was already marked as spam + let "t.SPAM_FLAG" "1"; +} +if eval "contains_ignore_case(header.X-UI-Filterresults:X-UI-Out-Filterresults, 'junk')" { + # United Internet says this message is spam + let "t.UNITEDINTERNET_SPAM" "1"; +} + +# Compromised hosts +if eval "header.X-PHP-Originating-Script.exists" { + let "t.HAS_X_POS" "1"; + if eval "contains(header.X-PHP-Originating-Script, 'eval()')" { + let "t.X_PHP_EVAL" "1"; + } + if eval "contains(header.X-PHP-Originating-Script, '../')" { + let "t.HIDDEN_SOURCE_OBJ" "1"; + } +} +if eval "header.X-PHP-Script.exists" { + let "t.HAS_X_PHP_SCRIPT" "1"; + if eval "contains(header.X-PHP-Script, 'eval()')" { + let "t.X_PHP_EVAL" "1"; + } + if eval "contains(header.X-PHP-Script, 'sendmail.php')" { + let "t.PHP_XPS_PATTERN" "1"; + } + if eval "contains(header.X-PHP-Script, '../')" { + let "t.HIDDEN_SOURCE_OBJ" "1"; + } +} +if eval "header.X-Source:X-Source-Args:X-Source-Dir.exists" { + let "t.HAS_X_SOURCE" "1"; + if eval "contains(header.X-Source-Args, '../')" { + let "t.HIDDEN_SOURCE_OBJ" "1"; + } +} +if eval "contains(header.X-Authenticated-Sender, ': ')" { + let "t.HAS_X_AS" "1"; +} +if eval "contains(header.X-Get-Message-Sender-Via, 'authenticated_id:')" { + let "t.HAS_X_GMSV" "1"; +} +if eval "header.X-AntiAbuse.exists" { + let "t.HAS_X_ANTIABUSE" "1"; +} +if eval "header.X-Authentication-Warning.exists" { + let "t.HAS_XAW" "1"; +} + +# Check for empty delimiters in raw headers +let "raw_headers" "header.from:to:cc:subject:reply-to:date[*].raw"; +let "i" "count(raw_headers)"; +while "i > 0" { + let "i" "i - 1"; + if eval "!starts_with(raw_headers[i], ' ')" { + let "t.HEADER_EMPTY_DELIMITER" "1"; + break; + } +} diff --git a/resources/config/sieve/html.sieve b/resources/config/sieve/html.sieve index 8bef5cf5..3ba05d4c 100644 --- a/resources/config/sieve/html.sieve +++ b/resources/config/sieve/html.sieve @@ -5,8 +5,9 @@ if eval "header.content-type == 'text/html'" { } foreverypart { - if eval "is_body() && eq_ignore_case(header.content-type, 'text/html')" { + if eval "eq_ignore_case(header.content-type, 'text/html')" { # Tokenize HTML + let "is_body_part" "is_body()"; let "html_tokens" "tokenize_html(part.text)"; let "html_tokens_len" "len(html_tokens)"; let "html_char_count" "0"; @@ -19,6 +20,7 @@ foreverypart { let "in_head" "0"; let "in_body" "0"; let "in_anchor" "0"; + let "in_anchor_href_ip" "0"; let "in_anchor_href" ""; let "i" "0"; @@ -35,26 +37,44 @@ foreverypart { let "text" "to_lowercase(trim(strip_prefix(token, '_')))"; let "html_words" "html_words + len(tokenize_words(text))"; - if eval "starts_with(text, 'https://') || starts_with(text, 'http://')" { + let "uris" "tokenize_url(text, false)"; + + if eval "!is_empty(uris)" { let "has_uri" "1"; - if eval "in_anchor && !is_empty(in_anchor_href) && - uri_part(text, 'scheme') != uri_part(in_anchor_href, 'scheme')" { - # The anchor text contains a distinct scheme compared to the target URL - let "t.HTTP_TO_HTTPS" "1"; + let "uri" "uris[0]"; + + if eval "in_anchor && !is_empty(in_anchor_href)" { + if eval "contains(text, '://') && + uri_part(uri, 'scheme') != uri_part(in_anchor_href, 'scheme')" { + # The anchor text contains a distinct scheme compared to the target URL + let "t.HTTP_TO_HTTPS" "1"; + } + if eval "(!in_anchor_href_ip && (domain_part(uri_part(uri, 'host'), 'sld') != domain_part(uri_part(in_anchor_href, 'host'), 'sld'))) || + (in_anchor_href_ip && (uri_part(uri, 'host') != uri_part(in_anchor_href, 'host')))" { + let "t.PHISHING" "1"; + } } } elsif eval "!is_empty(text)" { let "has_text" "1"; } } } elsif eval "starts_with(token, '= 210" { - let "has_link_to_img" "1"; - } - if eval "dimensions > 100" { - # We assume that a single picture 100x200 contains approx 3 words of text - let "html_img_words" "html_img_words + dimensions / 100"; + if eval "in_anchor && dimensions >= 210" { + let "has_link_to_img" "1"; + } + if eval "dimensions > 100" { + # We assume that a single picture 100x200 contains approx 3 words of text + let "html_img_words" "html_img_words + dimensions / 100"; + } + + let "img_src" "html_attr(token, 'src')"; + if eval "starts_with(img_src, 'data:') && contains(img_src, ';base64,')" { + # Has Data URI encoding + let "t.HAS_DATA_URI" "1"; + } } } elsif eval "starts_with(token, '= 2048) && - (html_img_words / (html_words + html_img_words) > 0.5)" { - # Message contains more images than text - let "t.HTML_TEXT_IMG_RATIO" "1"; - } - if eval "has_uri && !has_text" { - let "t.BODY_URI_ONLY" "1"; + # Check for short HTML parts with a link to an image + if eval "has_link_to_img" { + if eval "html_char_count < 1024" { + let "t.HTML_SHORT_LINK_IMG_1" "1"; + } elsif eval "html_char_count < 1536" { + let "t.HTML_SHORT_LINK_IMG_2" "1"; + } elsif eval "html_char_count < 2048" { + let "t.HTML_SHORT_LINK_IMG_3" "1"; + } + } + + if eval "(!has_link_to_img || html_char_count >= 2048) && + (html_img_words / (html_words + html_img_words) > 0.5)" { + # Message contains more images than text + let "t.HTML_TEXT_IMG_RATIO" "1"; + } + + if eval "has_uri && !has_text" { + let "t.BODY_URI_ONLY" "1"; + } } } } diff --git a/resources/config/sieve/mime.sieve b/resources/config/sieve/mime.sieve new file mode 100644 index 00000000..8137c610 --- /dev/null +++ b/resources/config/sieve/mime.sieve @@ -0,0 +1,157 @@ +if eval "!header.mime-version.exists" { + if eval "header.content-type.exists || header.content-transfer-encoding.exists" { + let "t.MISSING_MIME_VERSION" "1"; + } +} elsif eval "header.mime-version.raw_name != 'MIME-Version'" { + let "t.MV_CASE" "1"; +} + +let "has_text_part" "0"; +let "is_encrypted" "0"; + +foreverypart { + let "type" "to_lowercase(header.content-type.type)"; + let "subtype" "to_lowercase(header.content-type.subtype)"; + let "cte" "header.content-transfer-encoding"; + let "part_is_attachment" "is_attachment()"; + + if eval "cte != '' && !is_lowercase(cte)" { + let "cte" "to_lowercase(cte)"; + let "t.CTE_CASE" "1"; + } + + if eval "ends_with(header.content-type.raw, ';')" { + # Content-Type header ends with a semi-colon + let "t.CT_EXTRA_SEMI" "1"; + } + + if eval "type == 'multipart'" { + if eval "subtype == 'alternative'" { + let "has_plain_part" "0"; + let "has_html_part" "0"; + + let "text_part_words" ""; + let "text_part_uris" "0"; + + let "html_part_words" ""; + let "html_part_uris" "0"; + + foreverypart { + let "ma_ct" "to_lowercase(header.content-type)"; + + if eval "!has_plain_part && ma_ct == 'text/plain'" { + let "text_part" "part.text"; + let "text_part_words" "tokenize_words(text_part)"; + let "text_part_uris" "count(tokenize_url(text_part, true))"; + let "has_plain_part" "1"; + } elsif eval "!has_html_part && ma_ct == 'text/html'" { + let "html_part" "html_to_text(part.text)"; + let "html_part_words" "tokenize_words(html_part)"; + let "html_part_uris" "count(tokenize_url(html_part, true))"; + let "has_html_part" "1"; + } + } + + # Multipart message mostly text/html MIME + if eval "has_html_part" { + if eval "!has_plain_part" { + let "t.MIME_MA_MISSING_TEXT" "1"; + } + } elsif eval "has_plain_part" { + let "t.MIME_MA_MISSING_HTML" "1"; + } + + # HTML and text parts are different + if eval "!t.R_PARTS_DIFFER && has_html_part && has_plain_part && + (!is_empty(text_part_words) || !is_empty(html_part_words)) && + cosine_similarity(text_part_words, html_part_words) < 0.95" { + let "t.R_PARTS_DIFFER" "1"; + } + + # Odd URI count between parts + if eval "text_part_uris != html_part_uris" { + set "t.URI_COUNT_ODD" "1"; + } + } elsif eval "subtype == 'mixed'" { + let "num_text_parts" "0"; + let "has_other_part" "0"; + + foreverypart { + if eval "eq_ignore_case(header.content-type.type, 'text') && !is_attachment()" { + let "num_text_parts" "num_text_parts + 1"; + } elsif eval "!eq_ignore_case(header.content-type.type, 'multipart')" { + let "has_other_part" "1"; + } + } + + # Found multipart/mixed without non-textual part + if eval "!has_other_part && num_text_parts < 3" { + let "t.CTYPE_MIXED_BOGUS" "1"; + } + } elsif eval "subtype == 'encrypted'" { + set "is_encrypted" "1"; + } + } elsif eval "type == 'text'" { + # MIME text part claims to be ASCII but isn't + if eval "cte == '' || cte == '7bit'" { + if eval "!is_ascii(part.raw)" { + let "t.R_BAD_CTE_7BIT" "1"; + } + } else { + if eval "cte == 'base64'" { + # Has text part encoded in base64 + let "t.MIME_BASE64_TEXT" "1"; + if eval "is_ascii(part.text)" { + # Has text part encoded in base64 that does not contain any 8bit characters + let "t.MIME_BASE64_TEXT_BOGUS" "1"; + } + } + + if eval "subtype == 'plain' && is_empty(header.content-type.attr.charset)" { + # Charset header is missing + let "t.R_MISSING_CHARSET" "1"; + } + } + let "has_text_part" "1"; + } elsif eval "type == 'application'" { + if eval "subtype == 'pkcs7-mime'" { + let "t.ENCRYPTED_SMIME" "1"; + let "part_is_attachment" "0"; + } elsif eval "subtype == 'pkcs7-signature'" { + let "t.SIGNED_SMIME" "1"; + let "part_is_attachment" "0"; + } elsif eval "subtype == 'pgp-encrypted'" { + let "t.ENCRYPTED_PGP" "1"; + let "part_is_attachment" "0"; + } elsif eval "subtype == 'pgp-signature'" { + let "t.SIGNED_PGP" "1"; + let "part_is_attachment" "0"; + } elsif eval "subtype == 'octet-stream'" { + if eval "!is_encrypted && + !header.content-id.exists && + (!header.content-disposition.exists || + (!eq_ignore_case(header.content-disposition.type, 'attachment') && + is_empty(header.content-disposition.attr.filename)))" { + let "t.CTYPE_MISSING_DISPOSITION" "1"; + } + } + } + + if eval "is_empty(type)" { + if eval "header.content-type.exists" { + let "t.BROKEN_CONTENT_TYPE" "1"; + } + } elsif eval "!header.Content-Disposition:Content-Transfer-Encoding:MIME-Version.exists && (type != 'text' || subtype != 'plain')" { + # Only Content-Type header without other MIME headers + let "t.MIME_HEADER_CTYPE_ONLY" "1"; + } + + if eval "part_is_attachment" { + # Has a MIME attachment + let "t.HAS_ATTACHMENT" "1"; + } +} + +if eval "has_text_part && (t.ENCRYPTED_SMIME || t.SIGNED_SMIME || t.ENCRYPTED_PGP || t.SIGNED_PGP)" { + let "t.BOGUS_ENCRYPTED_AND_TEXT" "1"; +} diff --git a/resources/config/sieve/recipient.sieve b/resources/config/sieve/recipient.sieve index 32aca51e..93aed0b5 100644 --- a/resources/config/sieve/recipient.sieve +++ b/resources/config/sieve/recipient.sieve @@ -17,8 +17,9 @@ if eval "!is_empty(to_raw)" { let "t.MISSING_TO" "1"; } -let "rcpt_addr" "to_lowercase(header.to:cc:bcc[*].addr[*])"; -let "rcpt_count" "count(winnow(rcpt_addr))"; +let "rcpt_addr" "dedup(to_lowercase(header.to:cc:bcc[*].addr[*]))"; +let "rcpt_addr_clean" "winnow(rcpt_addr)"; +let "rcpt_count" "count(rcpt_addr_clean)"; if eval "rcpt_count > 0" { if eval "rcpt_count == 1" { @@ -80,16 +81,24 @@ if eval "rcpt_count > 0" { } } + # Check if it is an into to info + if eval "!t.INFO_TO_INFO_LU && + local_part == 'info' && + eq_ignore_case(email_part(header.from.addr, 'local'), 'info') && + header.List-Unsubscribe.exists" { + let "t.INFO_TO_INFO_LU" "1"; + } + # Check for freemail or disposable domains let "domain" "domain_part(email_part(addr, 'domain'), 'sld')"; if eval "!is_empty(domain)" { - if string :list "${domain}" "spam/free-domains" { + if eval "lookup('spam/free-domains', domain)" { if eval "!t.FREEMAIL_TO && contains_ignore_case(header.to[*].addr[*], addr)" { let "t.FREEMAIL_TO" "1"; } elsif eval "!t.FREEMAIL_CC && contains_ignore_case(header.cc[*].addr[*], addr)" { let "t.FREEMAIL_CC" "1"; } - } elsif string :list "${domain}" "spam/disposable-domains" { + } elsif eval "lookup('spam/disposable-domains', domain)" { if eval "!t.DISPOSABLE_TO && contains_ignore_case(header.to[*].addr[*], addr)" { let "t.DISPOSABLE_TO" "1"; } elsif eval "!t.DISPOSABLE_CC && contains_ignore_case(header.cc[*].addr[*], addr)" { @@ -142,6 +151,58 @@ if eval "rcpt_count > 0" { starts_with(envelope.from, 'mailer-daemon@'))" { let "t.HFILTER_RCPT_BOUNCEMOREONE" "1"; } + + # Check for sorted recipients + if eval "rcpt_count >= 7 && sort(rcpt_addr_clean, false) == rcpt_addr_clean" { + let "t.SORTED_RECIPS" "1"; + } + + # Check for suspiciously similar recipients + if eval "!t.SORTED_RECIPS && rcpt_count => 5" { + let "i" "rcpt_count"; + let "hits" "0"; + let "combinations" "0"; + + while "i" { + let "i" "i - 1"; + let "j" "i"; + while "j" { + let "j" "j - 1"; + let "a" "rcpt_addr_clean[i]"; + let "b" "rcpt_addr_clean[j]"; + + if eval "levenshtein_distance(email_part(a, 'local'), email_part(b, 'local')) < 3" { + let "hits" "hits + 1"; + } + + let "a" "email_part(a, 'domain')"; + let "b" "email_part(b, 'domain')"; + + if eval "a != b && levenshtein_distance(a, b) < 4" { + let "hits" "hits + 1"; + } + + let "combinations" "combinations + 1"; + } + } + + if eval "hits / combinations > 0.65" { + let "t.SUSPICIOUS_RECIPS" "1"; + } + } + + # Check for spaces in recipient addresses + let "raw_to" "header.to:cc[*].raw"; + let "i" "len(raw_to)"; + while "i != 0" { + let "i" "i - 1"; + let "raw_addr" "rsplit(raw_to[i], '<')[0]"; + if eval "contains(raw_addr, '>') && (starts_with(raw_addr, ' ' ) || ends_with(raw_addr, ' >'))" { + let "t.TO_WRAPPED_IN_SPACES" "1"; + break; + } + } + } else { let "t.RCPT_COUNT_ZERO" "1"; diff --git a/resources/config/sieve/replyto.sieve b/resources/config/sieve/replyto.sieve index 594e3244..71e73819 100644 --- a/resources/config/sieve/replyto.sieve +++ b/resources/config/sieve/replyto.sieve @@ -49,13 +49,12 @@ if eval "!is_empty(rto_raw)" { } } - if string :list "${rto_domain}" "spam/free-domains" { + if eval "lookup('spam/free-domains', rto_domain)" { let "t.FREEMAIL_REPLYTO" "1"; - if allof(eval "rto_domain != from_domain", string :list "${from_domain}" "spam/free-domains") { + if eval "rto_domain != from_domain && lookup('spam/free-domains', from_domain)" { let "t.FREEMAIL_REPLYTO_NEQ_FROM_DOM" "1"; } - - } elsif string :list "${rto_domain}" "spam/disposable-domains" { + } elsif eval "lookup('spam/disposable-domains', rto_domain)" { let "t.DISPOSABLE_REPLYTO" "1"; } diff --git a/resources/config/sieve/subject.sieve b/resources/config/sieve/subject.sieve index 415954c1..a9c7db01 100644 --- a/resources/config/sieve/subject.sieve +++ b/resources/config/sieve/subject.sieve @@ -14,7 +14,7 @@ if eval "count_chars(thread_name) > 200" { let "t.SUBJ_VERY_LONG" "1"; } -if eval "contains(subject_lcase, 'http://') || contains(subject_lcase, 'https://')" { +if eval "!is_empty(tokenize_url(subject_lcase, true))" { # Subject contains a URL let "t.URL_IN_SUBJECT" "1"; } diff --git a/resources/config/sieve/url.sieve b/resources/config/sieve/url.sieve new file mode 100644 index 00000000..5373f8cc --- /dev/null +++ b/resources/config/sieve/url.sieve @@ -0,0 +1,114 @@ +let "text_body" "body.to_text"; +let "body_urls" "tokenize_url(text_body, false)"; +let "html_body_urls" "html_attrs(body.html, '', ['href', 'src'])"; +let "urls" "dedup(tokenize_url(header.subject, false) + body_urls + html_body_urls)"; + +if eval "(count(body_urls) == 1 || count(html_body_urls) == 1) && count(tokenize_words(text_body)) == 0" { + let "t.HFILTER_URL_ONLY" "1"; +} + +if eval "has_zwsp(urls)" { + let "t.ZERO_WIDTH_SPACE_URL" "1"; +} elsif eval "has_obscured(urls)" { + let "t.R_SUSPICIOUS_URL" "1"; +} + +let "i" "count(urls)"; +while "i > 0" { + let "i" "i - 1"; + let "url" "urls[i]"; + let "host" "uri_part(url, 'host')"; + + if eval "!is_empty(host)" { + let "is_ip" "is_ip_addr(host)"; + let "host" "puny_decode(host)"; + let "host_lc" "to_lowercase(host)"; + let "host_sld" "domain_part(host_lc, 'sld')"; + + if eval "!is_ip && + (!t.REDIRECTOR_URL || !t.URL_REDIRECTOR_NESTED) && + lookup('spam/redirectors', host_sld)" { + let "t.REDIRECTOR_URL" "1"; + let "redir_count" "1"; + + while "redir_count <= 5" { + # Use a custom user-agent and a 3 second timeout + let "url_redirect" "http_header(url, 'Location', 'Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/20100101 Firefox/118.0', 3000)"; + if eval "!is_empty(url_redirect)" { + let "url" "url_redirect"; + let "host" "uri_part(url, 'host')"; + let "is_ip" "is_ip_addr(host)"; + let "host" "puny_decode(host)"; + let "host_lc" "to_lowercase(host)"; + let "host_sld" "domain_part(host_lc, 'sld')"; + + if eval "!is_ip && lookup('spam/redirectors', host_sld)" { + let "redir_count" "redir_count + 1"; + } else { + break; + } + } else { + break; + } + } + + if eval "redir_count > 5" { + let "t.URL_REDIRECTOR_NESTED" "1"; + } + } + + let "url_lc" "to_lowercase(url)"; + let "query" "uri_part(url_lc, 'path_query')"; + if eval "!is_ip" { + if eval "!is_ascii(host)" { + let "host_cured" "cure_text(host)"; + if eval "host_lc != host_cured" { + if eval "dns_exists(host_cured, 'ip')" { + let "t.OMOGRAPH_URL" "1"; + } else { + let "t.CONFUSABLE_URL" "1"; + } + } + + if eval "!is_single_script(host)" { + let "t.R_MIXED_CHARSET_URL" "1"; + } + } else { + if eval "ends_with(host, 'googleusercontent.com') && starts_with(query, '/proxy/')" { + let "t.HAS_GUC_PROXY_URI" "1"; + } elsif eval "ends_with(host, 'firebasestorage.googleapis.com')" { + let "t.HAS_GOOGLE_FIREBASE_URL" "1"; + } elsif eval "starts_with(domain_part(host, 'sld'), 'google.') && contains(query, 'url?') " { + let "t.HAS_GOOGLE_REDIR" "1"; + } + } + + if eval "(contains(host_lc, 'ipfs.') || contains(query, '/ipfs')) && contains(query, '/qm')" { + # InterPlanetary File System (IPFS) gateway URL, likely malicious + let "t.HAS_IPFS_GATEWAY_URL" "1"; + } elsif eval "ends_with(host_lc, '.onion')" { + let "t.HAS_ONION_URI" "1"; + } + } else { + # URL is an ip address + let "t.R_SUSPICIOUS_URL" "1"; + } + + if eval "starts_with(query, '/wp-')" { + # Contains WordPress URIs + let "t.HAS_WP_URI" "1"; + if eval "starts_with(query, '/wp-content') | starts_with(query, '/wp-includes')" { + # URL that is pointing to a compromised WordPress installation + let "t.WP_COMPROMISED" "1"; + } + } + if eval "contains(query, '/../') && !contains(query, '/well-known') && !contains(query, '/well_known')" { + # Message contains URI with a hidden path + let "t.URI_HIDDEN_PATH" "1"; + } + } else { + # URL could not be parsed + let "t.R_SUSPICIOUS_URL" "1"; + } +} + diff --git a/resources/spamassassin/10_default_prefs.cf b/resources/spamassassin/10_default_prefs.cf deleted file mode 100644 index d63e608b..00000000 --- a/resources/spamassassin/10_default_prefs.cf +++ /dev/null @@ -1,184 +0,0 @@ -# SpamAssassin basic config file -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -# Default template. Try to keep it under 78 columns (inside the the dots below). -# ........................................................................ -clear_report_template -if can(Mail::SpamAssassin::Conf::feature_yesno_takes_args) -report Spam detection software, running on the system "_HOSTNAME_", -report has_YESNO(, NOT)_ identified this incoming email as_YESNO( possible,)_ spam. The original -report message has been attached to this so you can view it or label -else -report Spam detection software, running on the system "_HOSTNAME_", has -report identified this incoming email as possible spam. The original message -report has been attached to this so you can view it (if it isn't spam) or label -endif -report similar future email. If you have any questions, see -report _CONTACTADDRESS_ for details. -report -report Content preview: _PREVIEW_ -report -report Content analysis details: (_SCORE_ points, _REQD_ required) -report -report " pts rule name description" -report ---- ---------------------- -------------------------------------------------- -report _SUMMARY_ - -# ........................................................................ - -# A 'contact address' users should contact for more info. (replaces -# _CONTACTADDRESS_ above if present) -report_contact @@CONTACT_ADDRESS@@ - -########################################################################### - -# Unsafe-for-viewing message report template. -# -# ...................................................................... -clear_unsafe_report_template -unsafe_report The original message was not completely plain text, and may be unsafe to -unsafe_report open with some email clients; in particular, it may contain a virus, -unsafe_report or confirm that your address can receive spam. If you wish to view -unsafe_report it, it may be safer to save it to a file and open it with an editor. -# ...................................................................... - -########################################################################### -# Database configuration options. -# -# user_scores_dsn MUST be in the form: -# DBI:databasetype:databasename:hostname:port -# ex. DBI:mysql:spamassassin:localhost -# -# user_scores_sql_username is the authorized username to connect to DSN -# user_scores_sql_password is the password for the database username - -#user_scores_dsn DBI:mysql:spamassassin:localhost -#user_scores_sql_username spam -#user_scores_sql_password spamfilter - -########################################################################## -# Headers to be added to mail (can be overriden by users in -# ~/.spamassassin/user_prefs) -# Make sure the header stays entirely on one line here - -clear_headers - -#X-Spam-Checker-Version: SpamAssassin 2.60-cvs (1.188-2003-05-24-exp) -add_header all Checker-Version SpamAssassin _VERSION_ (_SUBVERSION_) on _HOSTNAME_ - -#X-Spam-Flag: YES -add_header spam Flag _YESNOCAPS_ - -#X-Spam-Level: ************* -add_header all Level _STARS(*)_ - -#X-Spam-Status: Yes, score=14.0 required=5.0 tests=BAYES_99,CALL_FREE -# DATE_IN_PAST_12_24,DCC_CHECK,DRASTIC_REDUCED,FROM_HAS_MIXED_NUMS -# FROM_HAS_MIXED_NUMS3,HOME_EMPLOYMENT,INVALID_DATE,INVALID_MSGID -# LINES_OF_YELLING,MSGID_HAS_NO_AT,NO_REAL_NAME,ONCE_IN_LIFETIME -# UNDISC_RECIPS autolearn=spam version=2.60-cvs -add_header all Status "_YESNO_, score=_SCORE_ required=_REQD_ tests=_TESTS_ autolearn=_AUTOLEARN_ version=_VERSION_" - -########################################################################### -# Default prefs values: users can override these in their -# ~/.spamassassin/user_prefs files. - -# How many points before a mail is considered spam. -required_score 5 - -# Mail using locales used in these country codes will not be marked -# as being possibly spam in a foreign language. -ok_locales all - -# Mail using languages used in these country codes will not be marked -# as being possibly spam in a foreign language. This is an expensive -# classification, so it is is disabled in init.pre by default. -ifplugin Mail::SpamAssassin::Plugin::TextCat -ok_languages all -endif # Mail::SpamAssassin::Plugin::TextCat - -# Mail which scores outside this range will be fed back into SpamAssassin's -# learning system automatically, to train the Bayesian scanner. -ifplugin Mail::SpamAssassin::Plugin::AutoLearnThreshold -bayes_auto_learn_threshold_nonspam 0.1 -bayes_auto_learn_threshold_spam 12.0 -endif # Mail::SpamAssassin::Plugin::AutoLearnThreshold - -# Set this to 0 to turn off auto-learning. -bayes_auto_learn 1 - -# report_safe controls the markup of spam. If you set it to 0, the message -# body of spam messages will not be modified -report_safe 1 - -# Headers to parse for originating IP address -if can(Mail::SpamAssassin::Conf::feature_originating_ip_headers) -clear_originating_ip_headers -originating_ip_headers X-Yahoo-Post-IP X-Originating-IP X-Apparently-From -originating_ip_headers X-SenderIP X-AOL-IP -originating_ip_headers X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp -endif - -if can(Mail::SpamAssassin::Conf::feature_dns_local_ports_permit_avoid) -# leave out the more densely populated port number ranges -dns_local_ports_avoid 0-11000 -# leave out some ephemeral ports, making them available to other programs -dns_local_ports_avoid 49152-49408 -# avoid IANA assigned high port numbers -dns_local_ports_avoid 11000-11001 11106 11111-11112 11161-11165 11201 11208 -dns_local_ports_avoid 11211 11319-11321 11367 11371 11600 11720 11751 11967 -dns_local_ports_avoid 12000-12008 12012-12013 12109 12121 12168 12172 12300 -dns_local_ports_avoid 12321-12322 12345 12753 13160 13216-13218 13223-13224 -dns_local_ports_avoid 13720-13722 13724 13782-13783 13785-13786 13818-13822 -dns_local_ports_avoid 13929 14000-14001 14033-14034 14141-14142 14145 14149 -dns_local_ports_avoid 14154 14250 14414 14936-14937 15000 15345 15363 15555 -dns_local_ports_avoid 15660 15740 16161 16309-16311 16360-16361 16367-16368 -dns_local_ports_avoid 16384 16900 16950 16991-16995 17007 17185 17219 17235 -dns_local_ports_avoid 17500 17729 17754-17756 18000 18181-18187 18241 18262 -dns_local_ports_avoid 18463 18634-18635 18769 18881 18888 19000 19191 19194 -dns_local_ports_avoid 19283 19315 19398 19410-19412 19539-19541 19999-20003 -dns_local_ports_avoid 20005 20014 20034 20046 20049 20167 20202 20222 20480 -dns_local_ports_avoid 20670 20999-21000 21554 21590 21800 21845-21849 -dns_local_ports_avoid 22000-22005 22273 22305 22343 22347 22350 22555 22763 -dns_local_ports_avoid 22800 22951 23000-23005 23272 23333 23400-23402 -dns_local_ports_avoid 24000-24006 24242 24249 24321 24386 24465 24554 -dns_local_ports_avoid 24676-24678 24680 24922 25000-25009 25793 25900-25903 -dns_local_ports_avoid 26000 26133 26208 26260-26263 26486-26487 26489 27345 -dns_local_ports_avoid 27442 27504 27782 27999-28000 28240 29167 30001-30002 -dns_local_ports_avoid 30260 30999 31416 31457 31620 31765 31948-31949 32034 -dns_local_ports_avoid 32249 32483 32635-32636 32767-32777 32801 32896 33123 -dns_local_ports_avoid 33331 33434 33656 34249 34378-34379 34962-34964 34980 -dns_local_ports_avoid 36001 36865 37475 37654 38201-38203 39681 40000 -dns_local_ports_avoid 40841-40843 41111 41794-41795 42508-42510 43188-43190 -dns_local_ports_avoid 43440-43441 44321-44322 44553 44818 45054 45678 45825 -dns_local_ports_avoid 45966 46999-47000 47557 47624 47806 47808 48000-48003 -dns_local_ports_avoid 48128-48129 48556 48619 -endif - -# Some common prefs settings can be set here, to take effect site-wide -# unless the user override them. See the user_prefs.template file for -# explanations. - - diff --git a/resources/spamassassin/10_hasbase.cf b/resources/spamassassin/10_hasbase.cf deleted file mode 100644 index 795b794a..00000000 --- a/resources/spamassassin/10_hasbase.cf +++ /dev/null @@ -1,89 +0,0 @@ -# SpamAssassin rules file: Base __HAS_* rules for meta rules -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -# PLEASE KEEP THIS TIDY - -# According to Bug 6781 - -# Header rules - - -header __HAS_SENDER exists:Sender - -header __HAS_FROM exists:From - -header __HAS_TO exists:To - -header __HAS_CC exists:CC - -header __HAS_REPLY_TO exists:Reply-To - -header __HAS_ORGANIZATION exists:Organization - -# Webmail - -# MUA & User Agents -header __HAS_UA exists:User-Agent -header __HAS_XMAIL exists:X-Mailer - - -# Other -header __HAS_DKIM_SIGHD exists:DKIM-Signature - -header __HAS_TNEF exists:X-MS-TNEF-Correlator - -header __HAS_ERRORS_TO exists:Errors-To -header __HAS_ORIGINALLY exists:X-Originally-To -header __HAS_LIST_ID exists:List-Id -header __HAS_X_BEEN_THERE exists:X-BeenThere -header __HAS_X_REF exists:References -header __HAS_IN_REPLY_TO exists:In-Reply-To -header __XPRIO exists:X-Priority -header __DISPONOT exists:Disposition-Notification-To -header __RRCPTO exists:Return-Receipt-To -header __OLDPEG exists:X-Confirm-Reading-To -header __AOL_IP exists:X-AOL-IP - - -# Rawbody rules - - - -# Mimeheader rules -# should be encapsulated in if ... endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -# Put rules below - - -# -endif - - - - -# URI rules - -uri __HAS_URI /./ diff --git a/resources/spamassassin/20_advance_fee.cf b/resources/spamassassin/20_advance_fee.cf deleted file mode 100644 index a8869101..00000000 --- a/resources/spamassassin/20_advance_fee.cf +++ /dev/null @@ -1,96 +0,0 @@ -# SpamAssassin rules file: advance fee fraud rules (Nigerian 419 scams) -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -# predicate naming used to avoid renumbering -# 1. assign new rules a random unique three letter sequence -# 2. sort on rule definition, not rule name - -header __FRAUD_VQE Subject =~ /^(?:Re:|\[.{1,10}\])?\s*(?:very )?urgent\s+(?:(?:and|&)\s+)?(?:confidential|assistance|business|attention|reply|response|help)\b/i - -body __FRAUD_DBI /(?:\bdollars?\b|\busd(?:ollars)?(?:[0-9]|\b)|\bus\$|\$[0-9,.]{6,}|\$[0-9].{0,8}[mb]illion|\$[0-9.,]{2,10} ?m|\beuros?\b|u[.]?s[.]? [0-9.]+ m)/i -body __FRAUD_KJV /(?:claim|concerning) (?:the|this) money/i -body __FRAUD_IRJ /(?:finance|holding|securit(?:ies|y)) (?:company|firm|storage house)/i -body __FRAUD_NEB /(?:government|bank) of nigeria/i -body __FRAUD_XJR /(?:who was a|as a|an? honest|you being a|to any) foreigner/i -body __FRAUD_DPR /\b(?:(?:respond|reply) (?:urgently|immediately)|(?:urgent|immediate|earliest) (?:reply|response))\b/i -body __FRAUD_PTS /\b(?:ass?ass?inat(?:ed|ion)|murder(?:e?d)?|kill(?:ed|ing)\b[^.]{0,99}\b(?:war veterans|rebels?))\b/i -body __FRAUD_BEP /\b(?:bank of nigeria|central bank of|trust bank|apex bank|amalgamated bank)\b/i -body __FRAUD_TDP /\b(?:business partner(?:s|ship)?|silent partner(?:s|ship)?)\b/i -body __FRAUD_GAN /\b(?:charles taylor|serena|abacha|gu[eéè]i|sese[- ]?seko|kabila)\b/i -body __FRAUD_IRT /\b(?:compliments? of the|dear friend|dear sir|yours faithfully|season'?s greetings)\b/i -body __FRAUD_AON /\b(?:confidential|private|alternate|alternative) (?:(?:e-? *)?mail)\b/i -body __FRAUD_WNY /\b(?:disburse?(?:ment)?|incurr?(?:ed)?|remunerr?at(?:ed?|ion)|remm?itt?(?:ed|ance|ing)?)\b/i -body __FRAUD_IPK /\b(?:in|to|visit) your country\b/i -body __FRAUD_QXX /\b(?:my name is|i am) (?:mrs?|engr|barrister|dr|prince(?:ss)?)[. ]/i -body __FRAUD_IOU /\b(?:no risks?|risk-? *free|free of risks?|100% safe)\b/i -body __FRAUD_EZY /\b(?:of|the) late president\b/i -body __FRAUD_MLY /\b(?:reply|respond)\b[^.]{0,50}\b(?:to|through)\b[^.]{0,50}\@\b/i -body __FRAUD_ZFJ /\b(?:wife|son|brother|daughter) of the late\b/i -body __FRAUD_KDT /\bU\.?S\.?(?:D\.?)?\s*(?:\$\s*)?(?:\d+,\d+,\d+|\d+\.\d+\.\d+|\d+(?:\.\d+)?\s*milli?on)/i -body __FRAUD_ULK /\baffidavits?\b/i -body __FRAUD_BGP /\battached to ticket number\b/i -body __FRAUD_FBI /\bdisburs/i -body __FRAUD_JBU /\bforeign account\b/i -body __FRAUD_YWW /\bfurnish you with\b/i -body __FRAUD_JYG /\bgive\s+you .{0,15}(?:fund|money|total|sum|contact|percent)\b/i -body __FRAUD_XVW /\bhonest cooperation\b/i -body __FRAUD_UUY /\blegitimate business(?:es)?\b/i -body __FRAUD_SNT /\blocate(?: .{1,20})? extended relative/i -body __FRAUD_LTX /\bmilli?on (?:.{1,25} thousand\s*)?(?:(?:united states|u\.?s\.?) dollars|(?i:U\.?S\.?D?))\b/i -body __FRAUD_JNB /\boperat(?:e|ing)\b[^.]{0,99}\b(?:for(?:ei|ie)gn|off-? ?shore|over-? ?seas?) (?:bank )?accounts?\b/i -body __FRAUD_QFY /\bover-? *(?:invoiced?|cost(?:s|ing)?)\b/i -body __FRAUD_WDR /\bprivate lawyer\b/i -body __FRAUD_WFC /\bsecur(?:e|ing) (?:the )?(?:funds?|monies)\b/i -body __FRAUD_AUM /\bthe desk of\b/i -body __FRAUD_MCQ /\btransaction\b.{1,30}\b(?:magnitude|diplomatic|strict|absolute|secret|confiden(?:tial|ce)|guarantee)/i -body __FRAUD_ETX /\byour\b[^.]{0,99}\b(?:contact (?:details|information)|private (?:e?[- ]?mail|telephone|tel|phone|fax))\b/i -body __FRAUD_PVN /as the beneficiary/i -body __FRAUD_FVU /award notification/i -body __FRAUD_CKF /computer ballot system/i -body __FRAUD_FCW /fiduciary agent/i -body __FRAUD_MQO /foreign (?:business partner|customer)/i -body __FRAUD_TCC /foreign (?:offshore )?(?:bank|account)/i -body __FRAUD_GBW /god gives .{1,10}second chance/i -body __FRAUD_NRG /i am contacting you/i -body __FRAUD_RLX /lott(?:o|ery) (?:co,?ordinator|international)/i -body __FRAUD_AXF /magnanimity/i -body __FRAUD_THJ /modalit(?:y|ies)/i -body __FRAUD_YQV /nigerian? (?:national|government)/i -body __FRAUD_YJA /over-invoice/i -body __FRAUD_YPO /the total sum/i -body __FRAUD_UOQ /vital documents/i - -# -# jhardin: temporarily disable to gauge and score ADVANCE_FEE_NEW rules in isolation -# -# meta ADVANCE_FEE_2 (__FRAUD_KJV + __FRAUD_IRJ + __FRAUD_NEB + __FRAUD_XJR + __FRAUD_EZY + __FRAUD_ZFJ + __FRAUD_KDT + __FRAUD_BGP + __FRAUD_FBI + __FRAUD_JBU + __FRAUD_JYG + __FRAUD_XVW + __FRAUD_SNT + __FRAUD_LTX + __FRAUD_MCQ + __FRAUD_PVN + __FRAUD_FVU + __FRAUD_CKF + __FRAUD_FCW + __FRAUD_MQO + __FRAUD_TCC + __FRAUD_GBW + __FRAUD_NRG + __FRAUD_RLX + __FRAUD_AXF + __FRAUD_THJ + __FRAUD_YQV + __FRAUD_YJA + __FRAUD_YPO + __FRAUD_UOQ + __FRAUD_DBI + __FRAUD_BEP + __FRAUD_DPR + __FRAUD_QXX + __FRAUD_QFY + __FRAUD_PTS + __FRAUD_TDP + __FRAUD_GAN + __FRAUD_IPK + __FRAUD_AON + __FRAUD_WNY + __FRAUD_AUM + __FRAUD_WFC + __FRAUD_YWW + __FRAUD_ULK + __FRAUD_IOU + __FRAUD_JNB + __FRAUD_IRT + __FRAUD_ETX + __FRAUD_WDR + __FRAUD_UUY + __FRAUD_MLY > 2) -# meta ADVANCE_FEE_3 (__FRAUD_KJV + __FRAUD_IRJ + __FRAUD_NEB + __FRAUD_XJR + __FRAUD_EZY + __FRAUD_ZFJ + __FRAUD_KDT + __FRAUD_BGP + __FRAUD_FBI + __FRAUD_JBU + __FRAUD_JYG + __FRAUD_XVW + __FRAUD_SNT + __FRAUD_LTX + __FRAUD_MCQ + __FRAUD_PVN + __FRAUD_FVU + __FRAUD_CKF + __FRAUD_FCW + __FRAUD_MQO + __FRAUD_TCC + __FRAUD_GBW + __FRAUD_NRG + __FRAUD_RLX + __FRAUD_AXF + __FRAUD_THJ + __FRAUD_YQV + __FRAUD_YJA + __FRAUD_YPO + __FRAUD_UOQ + __FRAUD_DBI + __FRAUD_BEP + __FRAUD_DPR + __FRAUD_QXX + __FRAUD_QFY + __FRAUD_PTS + __FRAUD_TDP + __FRAUD_GAN + __FRAUD_IPK + __FRAUD_AON + __FRAUD_WNY + __FRAUD_AUM + __FRAUD_WFC + __FRAUD_YWW + __FRAUD_ULK + __FRAUD_IOU + __FRAUD_JNB + __FRAUD_IRT + __FRAUD_ETX + __FRAUD_WDR + __FRAUD_UUY + __FRAUD_MLY > 3) -# meta ADVANCE_FEE_4 (__FRAUD_KJV + __FRAUD_IRJ + __FRAUD_NEB + __FRAUD_XJR + __FRAUD_EZY + __FRAUD_ZFJ + __FRAUD_KDT + __FRAUD_BGP + __FRAUD_FBI + __FRAUD_JBU + __FRAUD_JYG + __FRAUD_XVW + __FRAUD_SNT + __FRAUD_LTX + __FRAUD_MCQ + __FRAUD_PVN + __FRAUD_FVU + __FRAUD_CKF + __FRAUD_FCW + __FRAUD_MQO + __FRAUD_TCC + __FRAUD_GBW + __FRAUD_NRG + __FRAUD_RLX + __FRAUD_AXF + __FRAUD_THJ + __FRAUD_YQV + __FRAUD_YJA + __FRAUD_YPO + __FRAUD_UOQ + __FRAUD_DBI + __FRAUD_BEP + __FRAUD_DPR + __FRAUD_QXX + __FRAUD_QFY + __FRAUD_PTS + __FRAUD_TDP + __FRAUD_GAN + __FRAUD_IPK + __FRAUD_AON + __FRAUD_WNY + __FRAUD_AUM + __FRAUD_WFC + __FRAUD_YWW + __FRAUD_ULK + __FRAUD_IOU + __FRAUD_JNB + __FRAUD_IRT + __FRAUD_ETX + __FRAUD_WDR + __FRAUD_UUY + __FRAUD_MLY > 4) -# -# describe ADVANCE_FEE_2 Appears to be advance fee fraud (Nigerian 419) -# describe ADVANCE_FEE_3 Appears to be advance fee fraud (Nigerian 419) -# describe ADVANCE_FEE_4 Appears to be advance fee fraud (Nigerian 419) diff --git a/resources/spamassassin/20_aux_tlds.cf b/resources/spamassassin/20_aux_tlds.cf deleted file mode 100644 index 77c22da4..00000000 --- a/resources/spamassassin/20_aux_tlds.cf +++ /dev/null @@ -1,746 +0,0 @@ -# SpamAssassin - Auxiliary TLD Definitions -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -# This file replaces the SARE http://www.rulesemporium.com/rules/90_2tld.cf -# which will be deprecated as from 2010-05-01 - -# File updated 2014-09-17 to contain complete TLD lists, they are no longer -# hardcoded into SA codebase and Util/RegistrarBoundaries.pm is deprecated -# in favor of Mail::SpamAssassin::RegistryBoundaries. - - -# Let's clear the internal TLD list, we only want to read from this config -# file and ignore possible old hardcoded lists. -if can(Mail::SpamAssassin::Conf::feature_registryboundaries) -clear_util_rb -endif - - -# -# 1st level TLD list -# - -# Basic list can be obtained with the following command: -# wget https://data.iana.org/TLD/tlds-alpha-by-domain.txt -q -O - | tail -n+2 | perl -ne 'print lc' -# Current list may include more or less.. TODO easier maintenance? - -# util_rb_tld only accepts alpha (a-z) input before RegistryBoundaries was -# implemented in 3.4.1(?), put IDN TLDs with numeric, hyphen (0-9-) etc in -# this block -# -# For an up to date list of IDN TLDs that can be pasted into this block, run this command: -# wget https://data.iana.org/TLD/tlds-alpha-by-domain.txt -q -O - | grep -i '^xn--' | tr '\n' ' ' | fold -w 80 -s | perl -pe 's/\s+$//; s/.*/util_rb_tld \L$_\n/' -# Since version 4.0 the util_rb_tld also accepts Unicode IDN labels (encoded as UTF-8), e.g.: -# wget https://data.iana.org/TLD/tlds-alpha-by-domain.txt -q -O - | grep -i '^xn--' | idn -u | tr '\n' ' ' | fold -w 80 -s | perl -pe 's/\s+$//; s/.*/util_rb_tld \L$_\n/' - -if can(Mail::SpamAssassin::Conf::feature_registryboundaries) -# Updated 2022-10-18 -util_rb_tld xn--11b4c3d xn--1ck2e1b xn--1qqw23a xn--2scrj9c xn--30rr7y xn--3bst00m -util_rb_tld xn--3ds443g xn--3e0b707e xn--3hcrj9c xn--3pxu8k xn--42c2d9a xn--45br5cyl -util_rb_tld xn--45brj9c xn--45q11c xn--4dbrk0ce xn--4gbrim xn--54b7fta0cc xn--55qw42g -util_rb_tld xn--55qx5d xn--5su34j936bgsg xn--5tzm5g xn--6frz82g xn--6qq986b3xl xn--80adxhks -util_rb_tld xn--80ao21a xn--80aqecdr1a xn--80asehdb xn--80aswg xn--8y0a063a xn--90a3ac -util_rb_tld xn--90ae xn--90ais xn--9dbq2a xn--9et52u xn--9krt00a xn--b4w605ferd -util_rb_tld xn--bck1b9a5dre4c xn--c1avg xn--c2br7g xn--cck2b3b xn--cckwcxetd xn--cg4bki -util_rb_tld xn--clchc0ea0b2g2a9gcd xn--czr694b xn--czrs0t xn--czru2d xn--d1acj3b xn--d1alf -util_rb_tld xn--e1a4c xn--eckvdtc9d xn--efvy88h xn--fct429k xn--fhbei xn--fiq228c5hs -util_rb_tld xn--fiq64b xn--fiqs8s xn--fiqz9s xn--fjq720a xn--flw351e xn--fpcrj9c3d -util_rb_tld xn--fzc2c9e2c xn--fzys8d69uvgm xn--g2xx48c xn--gckr3f0f xn--gecrj9c xn--gk3at1e -util_rb_tld xn--h2breg3eve xn--h2brj9c xn--h2brj9c8c xn--hxt814e xn--i1b6b1a6a2e -util_rb_tld xn--imr513n xn--io0a7i xn--j1aef xn--j1amh xn--j6w193g xn--jlq480n2rg -util_rb_tld xn--jlq61u9w7b xn--jvr189m xn--kcrx77d1x4a xn--kprw13d xn--kpry57d xn--kput3i -util_rb_tld xn--l1acc xn--lgbbat1ad8j xn--mgb9awbf xn--mgba3a3ejt xn--mgba3a4f16a -util_rb_tld xn--mgba7c0bbn0a xn--mgbaakc7dvf xn--mgbaam7a8h xn--mgbab2bd xn--mgbah1a3hjkrd -util_rb_tld xn--mgbai9azgqp6j xn--mgbayh7gpa xn--mgbbh1a xn--mgbbh1a71e xn--mgbc0a9azcg -util_rb_tld xn--mgbca7dzdo xn--mgbcpq6gpa1a xn--mgberp4a5d4ar xn--mgbgu82a xn--mgbi4ecexp -util_rb_tld xn--mgbpl2fh xn--mgbt3dhd xn--mgbtx2b xn--mgbx4cd0ab xn--mix891f xn--mk1bu44c -util_rb_tld xn--mxtq1m xn--ngbc5azd xn--ngbe9e0a xn--ngbrx xn--node xn--nqv7f -util_rb_tld xn--nqv7fs00ema xn--nyqy26a xn--o3cw4h xn--ogbpf8fl xn--otu796d xn--p1acf -util_rb_tld xn--p1ai xn--pgbs0dh xn--pssy2u xn--q7ce6a xn--q9jyb4c xn--qcka1pmc xn--qxa6a -util_rb_tld xn--qxam xn--rhqv96g xn--rovu88b xn--rvc1e0am3e xn--s9brj9c xn--ses554g -util_rb_tld xn--t60b56a xn--tckwe xn--tiq49xqyj xn--unup4y xn--vermgensberater-ctb -util_rb_tld xn--vermgensberatung-pwb xn--vhquv xn--vuq861b xn--w4r85el8fhu5dnra xn--w4rs40l -util_rb_tld xn--wgbh1c xn--wgbl6a xn--xhq521b xn--xkc2al3hye2a xn--xkc2dl3a5ee0h xn--y9a3aq -util_rb_tld xn--yfro4i67o xn--ygbi2ammx xn--zfr164b -endif - -# Standard List -# For an up to date list of TLDs that can be pasted into this block, run this command: -# wget https://data.iana.org/TLD/tlds-alpha-by-domain.txt -q -O - | tail -n+2 | grep -vi '^xn--' | tr '\n' ' ' | fold -w 80 -s | perl -pe 's/\s+$//; s/.*/util_rb_tld \L$_\n/' - -# Updated 2022-10-18 -util_rb_tld aaa aarp abarth abb abbott abbvie abc able abogado abudhabi ac academy -util_rb_tld accenture accountant accountants aco actor ad adac ads adult ae aeg aero aetna -util_rb_tld af afl africa ag agakhan agency ai aig airbus airforce airtel akdn al alfaromeo -util_rb_tld alibaba alipay allfinanz allstate ally alsace alstom am amazon americanexpress -util_rb_tld americanfamily amex amfam amica amsterdam analytics android anquan anz ao aol -util_rb_tld apartments app apple aq aquarelle ar arab aramco archi army arpa art arte as -util_rb_tld asda asia associates at athleta attorney au auction audi audible audio auspost -util_rb_tld author auto autos avianca aw aws ax axa az azure ba baby baidu banamex -util_rb_tld bananarepublic band bank bar barcelona barclaycard barclays barefoot bargains -util_rb_tld baseball basketball bauhaus bayern bb bbc bbt bbva bcg bcn bd be beats beauty -util_rb_tld beer bentley berlin best bestbuy bet bf bg bh bharti bi bible bid bike bing -util_rb_tld bingo bio biz bj black blackfriday blockbuster blog bloomberg blue bm bms bmw -util_rb_tld bn bnpparibas bo boats boehringer bofa bom bond boo book booking bosch bostik -util_rb_tld boston bot boutique box br bradesco bridgestone broadway broker brother -util_rb_tld brussels bs bt build builders business buy buzz bv bw by bz bzh ca cab cafe cal -util_rb_tld call calvinklein cam camera camp canon capetown capital capitalone car caravan -util_rb_tld cards care career careers cars casa case cash casino cat catering catholic cba -util_rb_tld cbn cbre cbs cc cd center ceo cern cf cfa cfd cg ch chanel channel charity -util_rb_tld chase chat cheap chintai christmas chrome church ci cipriani circle cisco -util_rb_tld citadel citi citic city cityeats ck cl claims cleaning click clinic clinique -util_rb_tld clothing cloud club clubmed cm cn co coach codes coffee college cologne com -util_rb_tld comcast commbank community company compare computer comsec condos construction -util_rb_tld consulting contact contractors cooking cookingchannel cool coop corsica country -util_rb_tld coupon coupons courses cpa cr credit creditcard creditunion cricket crown crs -util_rb_tld cruise cruises cu cuisinella cv cw cx cy cymru cyou cz dabur dad dance data -util_rb_tld date dating datsun day dclk dds de deal dealer deals degree delivery dell -util_rb_tld deloitte delta democrat dental dentist desi design dev dhl diamonds diet -util_rb_tld digital direct directory discount discover dish diy dj dk dm dnp do docs doctor -util_rb_tld dog domains dot download drive dtv dubai dunlop dupont durban dvag dvr dz earth -util_rb_tld eat ec eco edeka edu education ee eg email emerck energy engineer engineering -util_rb_tld enterprises epson equipment er ericsson erni es esq estate et etisalat eu -util_rb_tld eurovision eus events exchange expert exposed express extraspace fage fail -util_rb_tld fairwinds faith family fan fans farm farmers fashion fast fedex feedback -util_rb_tld ferrari ferrero fi fiat fidelity fido film final finance financial fire -util_rb_tld firestone firmdale fish fishing fit fitness fj fk flickr flights flir florist -util_rb_tld flowers fly fm fo foo food foodnetwork football ford forex forsale forum -util_rb_tld foundation fox fr free fresenius frl frogans frontdoor frontier ftr fujitsu fun -util_rb_tld fund furniture futbol fyi ga gal gallery gallo gallup game games gap garden gay -util_rb_tld gb gbiz gd gdn ge gea gent genting george gf gg ggee gh gi gift gifts gives -util_rb_tld giving gl glass gle global globo gm gmail gmbh gmo gmx gn godaddy gold -util_rb_tld goldpoint golf goo goodyear goog google gop got gov gp gq gr grainger graphics -util_rb_tld gratis green gripe grocery group gs gt gu guardian gucci guge guide guitars -util_rb_tld guru gw gy hair hamburg hangout haus hbo hdfc hdfcbank health healthcare help -util_rb_tld helsinki here hermes hgtv hiphop hisamitsu hitachi hiv hk hkt hm hn hockey -util_rb_tld holdings holiday homedepot homegoods homes homesense honda horse hospital host -util_rb_tld hosting hot hoteles hotels hotmail house how hr hsbc ht hu hughes hyatt hyundai -util_rb_tld ibm icbc ice icu id ie ieee ifm ikano il im imamat imdb immo immobilien in inc -util_rb_tld industries infiniti info ing ink institute insurance insure int international -util_rb_tld intuit investments io ipiranga iq ir irish is ismaili ist istanbul it itau itv -util_rb_tld jaguar java jcb je jeep jetzt jewelry jio jll jm jmp jnj jo jobs joburg jot joy -util_rb_tld jp jpmorgan jprs juegos juniper kaufen kddi ke kerryhotels kerrylogistics -util_rb_tld kerryproperties kfh kg kh ki kia kids kim kinder kindle kitchen kiwi km kn -util_rb_tld koeln komatsu kosher kp kpmg kpn kr krd kred kuokgroup kw ky kyoto kz la -util_rb_tld lacaixa lamborghini lamer lancaster lancia land landrover lanxess lasalle lat -util_rb_tld latino latrobe law lawyer lb lc lds lease leclerc lefrak legal lego lexus lgbt -util_rb_tld li lidl life lifeinsurance lifestyle lighting like lilly limited limo lincoln -util_rb_tld linde link lipsy live living lk llc llp loan loans locker locus loft lol london -util_rb_tld lotte lotto love lpl lplfinancial lr ls lt ltd ltda lu lundbeck luxe luxury lv -util_rb_tld ly ma macys madrid maif maison makeup man management mango map market marketing -util_rb_tld markets marriott marshalls maserati mattel mba mc mckinsey md me med media meet -util_rb_tld melbourne meme memorial men menu merckmsd mg mh miami microsoft mil mini mint -util_rb_tld mit mitsubishi mk ml mlb mls mm mma mn mo mobi mobile moda moe moi mom monash -util_rb_tld money monster mormon mortgage moscow moto motorcycles mov movie mp mq mr ms msd -util_rb_tld mt mtn mtr mu museum music mutual mv mw mx my mz na nab nagoya name natura navy -util_rb_tld nba nc ne nec net netbank netflix network neustar new news next nextdirect -util_rb_tld nexus nf nfl ng ngo nhk ni nico nike nikon ninja nissan nissay nl no nokia -util_rb_tld northwesternmutual norton now nowruz nowtv np nr nra nrw ntt nu nyc nz obi -util_rb_tld observer office okinawa olayan olayangroup oldnavy ollo om omega one ong onl -util_rb_tld online ooo open oracle orange org organic origins osaka otsuka ott ovh pa page -util_rb_tld panasonic paris pars partners parts party passagens pay pccw pe pet pf pfizer -util_rb_tld pg ph pharmacy phd philips phone photo photography photos physio pics pictet -util_rb_tld pictures pid pin ping pink pioneer pizza pk pl place play playstation plumbing -util_rb_tld plus pm pn pnc pohl poker politie porn post pr pramerica praxi press prime pro -util_rb_tld prod productions prof progressive promo properties property protection pru -util_rb_tld prudential ps pt pub pw pwc py qa qpon quebec quest racing radio re read -util_rb_tld realestate realtor realty recipes red redstone redumbrella rehab reise reisen -util_rb_tld reit reliance ren rent rentals repair report republican rest restaurant review -util_rb_tld reviews rexroth rich richardli ricoh ril rio rip ro rocher rocks rodeo rogers -util_rb_tld room rs rsvp ru rugby ruhr run rw rwe ryukyu sa saarland safe safety sakura -util_rb_tld sale salon samsclub samsung sandvik sandvikcoromant sanofi sap sarl sas save -util_rb_tld saxo sb sbi sbs sc sca scb schaeffler schmidt scholarships school schule -util_rb_tld schwarz science scot sd se search seat secure security seek select sener -util_rb_tld services ses seven sew sex sexy sfr sg sh shangrila sharp shaw shell shia -util_rb_tld shiksha shoes shop shopping shouji show showtime si silk sina singles site sj -util_rb_tld sk ski skin sky skype sl sling sm smart smile sn sncf so soccer social softbank -util_rb_tld software sohu solar solutions song sony soy spa space sport spot sr srl ss st -util_rb_tld stada staples star statebank statefarm stc stcgroup stockholm storage store -util_rb_tld stream studio study style su sucks supplies supply support surf surgery suzuki -util_rb_tld sv swatch swiss sx sy sydney systems sz tab taipei talk taobao target -util_rb_tld tatamotors tatar tattoo tax taxi tc tci td tdk team tech technology tel temasek -util_rb_tld tennis teva tf tg th thd theater theatre tiaa tickets tienda tiffany tips tires -util_rb_tld tirol tj tjmaxx tjx tk tkmaxx tl tm tmall tn to today tokyo tools top toray -util_rb_tld toshiba total tours town toyota toys tr trade trading training travel -util_rb_tld travelchannel travelers travelersinsurance trust trv tt tube tui tunes tushu tv -util_rb_tld tvs tw tz ua ubank ubs ug uk unicom university uno uol ups us uy uz va -util_rb_tld vacations vana vanguard vc ve vegas ventures verisign versicherung vet vg vi -util_rb_tld viajes video vig viking villas vin vip virgin visa vision viva vivo vlaanderen -util_rb_tld vn vodka volkswagen volvo vote voting voto voyage vu vuelos wales walmart -util_rb_tld walter wang wanggou watch watches weather weatherchannel webcam weber website -util_rb_tld wed wedding weibo weir wf whoswho wien wiki williamhill win windows wine -util_rb_tld winners wme wolterskluwer woodside work works world wow ws wtc wtf xbox xerox -util_rb_tld xfinity xihuan xin xxx xyz yachts yahoo yamaxun yandex ye yodobashi yoga -util_rb_tld yokohama you youtube yt yun za zappos zara zero zip zm zone zuerich zw - -# -# 2nd level TLD list -# - -# http://www.neustar.us/policies/docs/rfc_1480.txt -# data originally from http://spamcheck.freeapp.net/two-level-tlds -# The freeapp.net site now says that information on the site is obsolete -# See discussion and sources in comments of bug 5677 -# updated as per bug 5815 -# cleanup in progress per bug 6795 (axb) -# Unsorted sources: -# .ua : https://hostmaster.ua -# .hu : http://www.domain.hu/domain/English/szabalyzat/sld.html - -util_rb_2tld com.ac edu.ac gov.ac mil.ac net.ac org.ac -util_rb_2tld nom.ad -util_rb_2tld ac.ae co.ae com.ae gov.ae mil.ae name.ae net.ae org.ae pro.ae sch.ae -util_rb_2tld com.af edu.af gov.af net.af -util_rb_2tld co.ag com.ag net.ag nom.ag org.ag -util_rb_2tld com.ai edu.ai gov.ai net.ai off.ai org.ai -util_rb_2tld com.al edu.al gov.al net.al org.al -util_rb_2tld com.an edu.an net.an org.an -util_rb_2tld co.ao ed.ao gv.ao it.ao og.ao pb.ao -util_rb_2tld com.ar edu.ar gov.ar int.ar mil.ar net.ar org.ar -util_rb_2tld e164.arpa in-addr.arpa ip6.arpa iris.arpa uri.arpa urn.arpa -util_rb_2tld ac.at co.at gv.at or.at priv.at -util_rb_2tld act.au asn.au com.au conf.au csiro.au edu.au gov.au id.au info.au net.au nsw.au nt.au org.au otc.au oz.au qld.au sa.au tas.au telememo.au vic.au wa.au -util_rb_2tld com.aw -util_rb_2tld biz.az com.az edu.az gov.az info.az int.az mil.az name.az net.az org.az pp.az -util_rb_2tld co.ba com.ba edu.ba gov.ba mil.ba net.ba org.ba rs.ba unbi.ba unsa.ba -util_rb_2tld com.bb edu.bb gov.bb net.bb org.bb -util_rb_2tld ac.bd com.bd edu.bd gov.bd mil.bd net.bd org.bd -util_rb_2tld ac.be belgie.be dns.be fgov.be -util_rb_2tld gov.bf -util_rb_2tld biz.bh cc.bh com.bh edu.bh gov.bh info.bh net.bh org.bh -util_rb_2tld com.bm edu.bm gov.bm net.bm org.bm -util_rb_2tld com.bn edu.bn net.bn org.bn -util_rb_2tld com.bo edu.bo gob.bo gov.bo int.bo mil.bo net.bo org.bo tv.bo -util_rb_2tld adm.br adv.br agr.br am.br arq.br art.br ato.br bio.br bmd.br cim.br cng.br cnt.br com.br coop.br dpn.br eco.br ecn.br edu.br eng.br esp.br etc.br eti.br far.br fm.br fnd.br fot.br fst.br g12.br ggf.br gov.br imb.br ind.br inf.br jor.br lel.br mat.br med.br mil.br mus.br net.br nom.br not.br ntr.br odo.br org.br ppg.br pro.br psc.br psi.br qsl.br rec.br slg.br srv.br tmp.br trd.br tur.br tv.br vet.br zlg.br -util_rb_2tld com.bs net.bs org.bs -util_rb_2tld com.bt edu.bt gov.bt net.bt org.bt -util_rb_2tld co.bw org.bw -util_rb_2tld gov.by mil.by -util_rb_2tld com.bz net.bz org.bz -util_rb_2tld ab.ca bc.ca gc.ca mb.ca nb.ca nf.ca nl.ca ns.ca nt.ca nu.ca on.ca pe.ca qc.ca sk.ca yk.ca -util_rb_2tld co.ck edu.ck gov.ck net.ck org.ck -util_rb_2tld ac.cn ah.cn bj.cn com.cn cq.cn edu.cn fj.cn gd.cn gov.cn gs.cn gx.cn gz.cn ha.cn hb.cn he.cn hi.cn hk.cn hl.cn hn.cn jl.cn js.cn jx.cn ln.cn mo.cn net.cn nm.cn nx.cn org.cn qh.cn sc.cn sd.cn sh.cn sn.cn sx.cn tj.cn tw.cn xj.cn xz.cn yn.cn zj.cn -util_rb_2tld arts.co com.co edu.co firm.co gov.co info.co int.co mil.co net.co nom.co org.co rec.co web.co -util_rb_2tld co.cm com.cm net.cm -util_rb_2tld au.com br.com cn.com de.com eu.com gb.com hu.com no.com qc.com ru.com sa.com se.com uk.com us.com uy.com za.com -util_rb_2tld ac.cr co.cr ed.cr fi.cr go.cr or.cr sa.cr -util_rb_2tld com.cu edu.cu gov.cu inf.cu net.cu org.cu -util_rb_2tld gov.cx -util_rb_2tld ac.cy biz.cy com.cy ekloges.cy gov.cy ltd.cy name.cy net.cy org.cy parliament.cy press.cy pro.cy tm.cy -util_rb_2tld co.dk -util_rb_2tld com.dm edu.dm gov.dm net.dm org.dm -util_rb_2tld art.do com.do edu.do gob.do gov.do mil.do net.do org.do sld.do web.do -util_rb_2tld art.dz asso.dz com.dz edu.dz gov.dz net.dz org.dz pol.dz -util_rb_2tld com.ec edu.ec fin.ec gov.ec info.ec k12.ec med.ec mil.ec net.ec org.ec pro.ec gob.ec -util_rb_2tld co.ee com.ee edu.ee fie.ee med.ee org.ee pri.ee -util_rb_2tld com.eg edu.eg eun.eg gov.eg mil.eg net.eg org.eg sci.eg -util_rb_2tld com.er edu.er gov.er ind.er mil.er net.er org.er -util_rb_2tld com.es edu.es gob.es nom.es org.es -util_rb_2tld biz.et com.et edu.et gov.et info.et name.et net.et org.et -util_rb_2tld aland.fi -util_rb_2tld ac.fj biz.fj com.fj gov.fj id.fj info.fj mil.fj name.fj net.fj org.fj pro.fj school.fj -util_rb_2tld ac.fk co.fk com.fk gov.fk net.fk nom.fk org.fk -util_rb_2tld tm.fr asso.fr nom.fr prd.fr presse.fr com.fr gouv.fr -util_rb_2tld com.ge edu.ge gov.ge mil.ge net.ge org.ge pvt.ge -util_rb_2tld ac.gg alderney.gg co.gg gov.gg guernsey.gg ind.gg ltd.gg net.gg org.gg sark.gg sch.gg -util_rb_2tld com.gh edu.gh gov.gh mil.gh org.gh -util_rb_2tld com.gi edu.gi gov.gi ltd.gi mod.gi org.gi -util_rb_2tld ac.gn com.gn gov.gn net.gn org.gn -util_rb_2tld asso.gp com.gp edu.gp net.gp org.gp -util_rb_2tld com.gr edu.gr gov.gr net.gr org.gr -util_rb_2tld com.gt edu.gt gob.gt ind.gt mil.gt net.gt org.gt -util_rb_2tld com.gu edu.gu gov.gu mil.gu net.gu org.gu -util_rb_2tld com.hk edu.hk gov.hk idv.hk net.hk org.hk -util_rb_2tld com.hn edu.hn gob.hn mil.hn net.hn org.hn -util_rb_2tld com.hr from.hr iz.hr name.hr -util_rb_2tld adult.ht art.ht asso.ht com.ht coop.ht edu.ht firm.ht gouv.ht info.ht med.ht net.ht org.ht perso.ht pol.ht pro.ht rel.ht shop.ht -util_rb_2tld 2000.hu agrar.hu bolt.hu casino.hu city.hu co.hu erotica.hu erotika.hu film.hu forum.hu games.hu hotel.hu info.hu ingatlan.hu jogasz.hu konyvelo.hu lakas.hu media.hu news.hu org.hu priv.hu reklam.hu sex.hu shop.hu sport.hu suli.hu szex.hu tm.hu tozsde.hu utazas.hu video.hu -util_rb_2tld ac.id co.id go.id mil.id net.id or.id sch.id web.id -util_rb_2tld gov.ie -util_rb_2tld ac.il co.il gov.il idf.il k12.il muni.il net.il org.il -util_rb_2tld ac.im co.im com.im gov.im net.im nic.im org.im -util_rb_2tld ac.in co.in edu.in ernet.in firm.in gen.in gov.in ind.in mil.in net.in nic.in org.in res.in -util_rb_2tld com.io gov.io mil.io net.io org.io -util_rb_2tld gov.iq -util_rb_2tld ac.ir co.ir gov.ir id.ir net.ir org.ir sch.ir -util_rb_2tld edu.it gov.it -util_rb_2tld ac.je co.je gov.je ind.je jersey.je ltd.je net.je org.je sch.je -util_rb_2tld com.jm edu.jm gov.jm net.jm org.jm -util_rb_2tld com.jo edu.jo gov.jo mil.jo net.jo org.jo -util_rb_2tld ac.jp ad.jp aichi.jp akita.jp aomori.jp chiba.jp co.jp ed.jp ehime.jp fukui.jp fukuoka.jp fukushima.jp gifu.jp go.jp gov.jp gr.jp gunma.jp hiroshima.jp hokkaido.jp hyogo.jp ibaraki.jp ishikawa.jp iwate.jp kagawa.jp kagoshima.jp kanagawa.jp kanazawa.jp kawasaki.jp kitakyushu.jp kobe.jp kochi.jp kumamoto.jp kyoto.jp lg.jp matsuyama.jp mie.jp miyagi.jp miyazaki.jp nagano.jp nagasaki.jp nagoya.jp nara.jp ne.jp net.jp niigata.jp oita.jp okayama.jp okinawa.jp or.jp org.jp osaka.jp saga.jp saitama.jp sapporo.jp sendai.jp shiga.jp shimane.jp shizuoka.jp takamatsu.jp tochigi.jp tokushima.jp tokyo.jp tottori.jp toyama.jp utsunomiya.jp wakayama.jp yamagata.jp yamaguchi.jp yamanashi.jp yokohama.jp -util_rb_2tld ac.ke co.ke go.ke ne.ke new.ke or.ke sc.ke -util_rb_2tld com.kg edu.kg gov.kg mil.kg net.kg org.kg -util_rb_2tld com.kh edu.kh gov.kh mil.kh net.kh org.kh per.kh -util_rb_2tld ac.kr busan.kr chungbuk.kr chungnam.kr co.kr daegu.kr daejeon.kr es.kr gangwon.kr go.kr gwangju.kr gyeongbuk.kr gyeonggi.kr gyeongnam.kr hs.kr incheon.kr jeju.kr jeonbuk.kr jeonnam.kr kg.kr kyonggi.kr mil.kr ms.kr ne.kr or.kr pe.kr re.kr sc.kr seoul.kr ulsan.kr -util_rb_2tld com.kw edu.kw gov.kw mil.kw net.kw org.kw -util_rb_2tld com.ky edu.ky gov.ky net.ky org.ky -util_rb_2tld com.kz edu.kz gov.kz mil.kz net.kz org.kz -util_rb_2tld com.la net.la org.la -util_rb_2tld com.lb edu.lb gov.lb mil.lb net.lb org.lb -util_rb_2tld com.lc edu.lc gov.lc net.lc org.lc -util_rb_2tld assn.lk com.lk edu.lk gov.lk grp.lk hotel.lk int.lk ltd.lk net.lk ngo.lk org.lk sch.lk soc.lk web.lk -util_rb_2tld com.lr edu.lr gov.lr net.lr org.lr -util_rb_2tld co.ls org.ls -util_rb_2tld gov.lt mil.lt -util_rb_2tld asn.lv com.lv conf.lv edu.lv gov.lv id.lv mil.lv net.lv org.lv -util_rb_2tld biz.ly com.ly edu.ly gov.ly id.ly med.ly net.ly org.ly plc.ly sch.ly -util_rb_2tld ac.ma co.ma gov.ma net.ma org.ma press.ma -util_rb_2tld asso.mc tm.mc -util_rb_2tld ac.me co.me edu.me gov.me its.me net.me org.me priv.me -util_rb_2tld com.mg edu.mg gov.mg mil.mg nom.mg org.mg prd.mg tm.mg -util_rb_2tld army.mil navy.mil -util_rb_2tld com.mk org.mk -util_rb_2tld com.mm edu.mm gov.mm net.mm org.mm -util_rb_2tld edu.mn gov.mn org.mn -util_rb_2tld com.mo edu.mo gov.mo net.mo org.mo -util_rb_2tld music.mobi weather.mobi -util_rb_2tld co.mp edu.mp gov.mp net.mp org.mp -util_rb_2tld com.mt edu.mt gov.mt net.mt org.mt tm.mt uu.mt -util_rb_2tld co.mu com.mu -util_rb_2tld aero.mv biz.mv com.mv coop.mv edu.mv gov.mv info.mv int.mv mil.mv museum.mv name.mv net.mv org.mv pro.mv -util_rb_2tld ac.mw co.mw com.mw coop.mw edu.mw gov.mw int.mw museum.mw net.mw org.mw -util_rb_2tld com.mx edu.mx gob.mx net.mx org.mx -util_rb_2tld com.my edu.my gov.my mil.my name.my net.my org.my -util_rb_2tld co.mz net.mz org.mz ac.mz gov.mz edu.mz -util_rb_2tld alt.na com.na cul.na edu.na net.na org.na telecom.na unam.na -util_rb_2tld com.nc net.nc org.nc -util_rb_2tld de.net gb.net uk.net -util_rb_2tld ac.ng com.ng edu.ng gov.ng net.ng org.ng sch.ng -util_rb_2tld ac.ni biz.ni com.ni edu.ni gob.ni in.ni info.ni int.ni mil.ni net.ni nom.ni org.ni web.ni -util_rb_2tld fhs.no folkebibl.no fylkesbibl.no herad.no idrett.no kommune.no mil.no museum.no priv.no stat.no tel.no vgs.no -util_rb_2tld com.np edu.np gov.np mil.np net.np org.np -util_rb_2tld biz.nr co.nr com.nr edu.nr fax.nr gov.nr info.nr mob.nr mobil.nr mobile.nr net.nr org.nr tel.nr tlf.nr -util_rb_2tld ac.nz co.nz cri.nz geek.nz gen.nz govt.nz iwi.nz kiwi.nz maori.nz mil.nz net.nz org.nz parliament.nz school.nz -util_rb_2tld ac.om biz.om co.om com.om edu.om gov.om med.om mil.om mod.om museum.om net.om org.om pro.om sch.om -util_rb_2tld dk.org eu.org -util_rb_2tld abo.pa ac.pa com.pa edu.pa gob.pa ing.pa med.pa net.pa nom.pa org.pa sld.pa -util_rb_2tld com.pe edu.pe gob.pe mil.pe net.pe nom.pe org.pe -util_rb_2tld com.pf edu.pf org.pf -util_rb_2tld ac.pg com.pg net.pg -util_rb_2tld com.ph edu.ph gov.ph mil.ph net.ph ngo.ph org.ph -util_rb_2tld biz.pk com.pk edu.pk fam.pk gob.pk gok.pk gon.pk gop.pk gos.pk gov.pk net.pk org.pk web.pk -util_rb_2tld art.pl biz.pl com.pl edu.pl gov.pl info.pl mil.pl net.pl ngo.pl org.pl -util_rb_2tld biz.pr com.pr edu.pr gov.pr info.pr isla.pr name.pr net.pr org.pr pro.pr -util_rb_2tld cpa.pro law.pro med.pro -util_rb_2tld com.ps edu.ps gov.ps net.ps org.ps plo.ps sec.ps -util_rb_2tld com.pt edu.pt gov.pt int.pt net.pt nome.pt org.pt publ.pt -util_rb_2tld com.py edu.py gov.py net.py org.py -util_rb_2tld com.qa edu.qa gov.qa net.qa org.qa -util_rb_2tld asso.re com.re nom.re -util_rb_2tld arts.ro com.ro firm.ro info.ro nom.ro nt.ro org.ro rec.ro store.ro tm.ro www.ro -util_rb_2tld ac.rs co.rs edu.rs gov.rs in.rs org.rs -util_rb_2tld ac.ru com.ru edu.ru gov.ru int.ru mil.ru net.ru org.ru pp.ru -util_rb_2tld ac.rw co.rw com.rw edu.rw gouv.rw gov.rw int.rw mil.rw net.rw -util_rb_2tld com.sa edu.sa gov.sa med.sa net.sa org.sa pub.sa sch.sa -util_rb_2tld com.sb edu.sb gov.sb net.sb org.sb -util_rb_2tld com.sc edu.sc gov.sc net.sc org.sc -util_rb_2tld com.sd edu.sd gov.sd info.sd med.sd net.sd org.sd sch.sd tv.sd -util_rb_2tld ab.se ac.se bd.se brand.se c.se d.se e.se f.se fh.se fhsk.se fhv.se g.se h.se i.se k.se komforb.se kommunalforbund.se komvux.se lanarb.se lanbib.se m.se mil.se n.se naturbruksgymn.se o.se org.se parti.se pp.se press.se s.se sshn.se t.se tm.se u.se w.se x.se y.se z.se -util_rb_2tld com.sg edu.sg gov.sg idn.sg net.sg org.sg per.sg -util_rb_2tld com.sh edu.sh gov.sh mil.sh net.sh org.sh -util_rb_2tld edu.sk gov.sk mil.sk -util_rb_2tld co.st com.st consulado.st edu.st embaixada.st gov.st mil.st net.st org.st principe.st saotome.st store.st -util_rb_2tld com.sv edu.sv gob.sv org.sv red.sv -util_rb_2tld com.sy gov.sy net.sy org.sy -util_rb_2tld at.tf bg.tf ca.tf ch.tf cz.tf de.tf edu.tf eu.tf int.tf net.tf pl.tf ru.tf sg.tf us.tf -util_rb_2tld ac.th co.th go.th in.th mi.th net.th or.th -util_rb_2tld ac.tj biz.tj co.tj com.tj edu.tj go.tj gov.tj int.tj mil.tj name.tj net.tj org.tj web.tj -util_rb_2tld com.tn edunet.tn ens.tn fin.tn gov.tn ind.tn info.tn intl.tn nat.tn net.tn org.tn rnrt.tn rns.tn rnu.tn tourism.tn -util_rb_2tld gov.to -util_rb_2tld gov.tp -util_rb_2tld av.tr bbs.tr bel.tr biz.tr com.tr dr.tr edu.tr gen.tr gov.tr info.tr k12.tr mil.tr name.tr net.tr org.tr pol.tr tel.tr web.tr -util_rb_2tld aero.tt at.tt au.tt be.tt biz.tt ca.tt co.tt com.tt coop.tt de.tt dk.tt edu.tt es.tt eu.tt fr.tt gov.tt info.tt int.tt it.tt jobs.tt mobi.tt museum.tt name.tt net.tt nic.tt org.tt pro.tt se.tt travel.tt uk.tt us.tt -util_rb_2tld co.tv gov.tv -util_rb_2tld club.tw com.tw ebiz.tw edu.tw game.tw gov.tw idv.tw mil.tw net.tw org.tw -util_rb_2tld ac.tz co.tz go.tz ne.tz or.tz -util_rb_2tld cherkassy.ua chernigov.ua chernovtsy.ua ck.ua cn.ua co.ua com.ua crimea.ua cv.ua dn.ua dnepropetrovsk.ua donetsk.ua dp.ua edu.ua gov.ua if.ua in.ua ivano-frankivsk.ua kh.ua kharkov.ua kherson.ua khmelnitskiy.ua kiev.ua kirovograd.ua km.ua kr.ua ks.ua kv.ua lg.ua lugansk.ua lutsk.ua lviv.ua mk.ua net.ua nikolaev.ua od.ua odessa.ua org.ua pl.ua poltava.ua rovno.ua rv.ua sebastopol.ua sumy.ua te.ua ternopil.ua uzhgorod.ua vinnica.ua vn.ua zaporizhzhe.ua zhitomir.ua zp.ua zt.ua -util_rb_2tld ac.ug co.ug go.ug ne.ug or.ug sc.ug -util_rb_2tld ac.uk bl.uk british-library.uk co.uk edu.uk gov.uk icnet.uk jet.uk ltd.uk me.uk mod.uk national-library-scotland.uk net.uk nhs.uk nic.uk nls.uk org.uk parliament.uk plc.uk police.uk sch.uk -util_rb_2tld ak.us al.us ar.us az.us ca.us co.us ct.us dc.us de.us dni.us fed.us fl.us ga.us hi.us ia.us id.us il.us in.us isa.us kids.us ks.us ky.us la.us ma.us md.us me.us mi.us mn.us mo.us ms.us mt.us nc.us nd.us ne.us nh.us nj.us nm.us nsn.us nv.us ny.us oh.us ok.us or.us pa.us ri.us sc.us sd.us tn.us tx.us ut.us va.us vt.us wa.us wi.us wv.us wy.us -util_rb_2tld com.uy edu.uy gub.uy mil.uy net.uy org.uy -util_rb_2tld vatican.va -util_rb_2tld arts.ve bib.ve co.ve com.ve edu.ve firm.ve gov.ve info.ve int.ve mil.ve net.ve nom.ve org.ve rec.ve store.ve tec.ve web.ve -util_rb_2tld co.vi com.vi edu.vi gov.vi net.vi org.vi -util_rb_2tld ac.vn biz.vn com.vn edu.vn gov.vn health.vn info.vn int.vn name.vn net.vn org.vn pro.vn -util_rb_2tld ch.vu com.vu de.vu edu.vu fr.vu net.vu org.vu -util_rb_2tld com.ws edu.ws gov.ws net.ws org.ws -util_rb_2tld com.ye edu.ye gov.ye mil.ye net.ye org.ye -util_rb_2tld ac.za alt.za bourse.za city.za co.za edu.za gov.za law.za mil.za net.za ngo.za nom.za org.za school.za tm.za web.za -util_rb_2tld ac.zm co.zm com.zm edu.zm gov.zm org.zm sch.zm -util_rb_2tld ac.zw co.zw gov.zw org.zw -# -util_rb_2tld 110mb.com -util_rb_2tld 9k.com -util_rb_2tld addr.com -util_rb_2tld altervista.org -util_rb_2tld biz.tm -util_rb_2tld blogger.ca -util_rb_2tld blogger.cf -util_rb_2tld blogger.ch -util_rb_2tld blogspot.com -util_rb_2tld blogger.cv -util_rb_2tld blogger.jp -util_rb_2tld blogger.pl -util_rb_2tld blogger.re -util_rb_2tld blogger.se -util_rb_2tld blogspot.ca -util_rb_2tld blogspot.cv -util_rb_2tld blogspot.de -util_rb_2tld blogspot.fr -util_rb_2tld blogspot.in -util_rb_2tld blogspot.it -util_rb_2tld blogspot.jp -util_rb_2tld blogspot.mx -util_rb_2tld blogspot.pt -util_rb_2tld blogspot.re -util_rb_2tld blogspot.se -util_rb_2tld bravehost.com -util_rb_2tld bravejournal.com -util_rb_2tld by.ru -util_rb_2tld chat.ru -util_rb_2tld cjb.net -util_rb_2tld es.tl -util_rb_2tld extra.hu -util_rb_2tld freehostia.com -util_rb_2tld front.ru -util_rb_2tld geocities.com -util_rb_2tld getmyip.com -util_rb_2tld googlepages.com -util_rb_2tld helloweb.eu -util_rb_2tld host.sk -util_rb_2tld hotbox.ru -util_rb_2tld hotmail.ru -util_rb_2tld hu2.ru -util_rb_2tld hut2.ru -util_rb_2tld iblogger.org -util_rb_2tld ic.cz -util_rb_2tld id.ru -util_rb_2tld kwik.to -util_rb_2tld land.ru -util_rb_2tld mine.nu -util_rb_2tld mooo.com -util_rb_2tld narod.ru -util_rb_2tld netsolhost.com -util_rb_2tld na.by -util_rb_2tld newmail.ru -util_rb_2tld nextmail.ru -util_rb_2tld nightmail.ru -util_rb_2tld nm.ru -util_rb_2tld notlong.com -util_rb_2tld page.tl page.link -util_rb_2tld pochta.ru -util_rb_2tld pochtamt.ru -util_rb_2tld pop3.ru -util_rb_2tld proboards.com -util_rb_2tld rbcmail.ru -util_rb_2tld rm.ru -util_rb_2tld smtp.ru -util_rb_2tld sol.ru -util_rb_2tld t35.com -util_rb_2tld tripod.com -util_rb_2tld uk.to -util_rb_2tld unblog.fr -util_rb_2tld us.to -util_rb_2tld web-soft.ru -util_rb_2tld wz.cz -util_rb_2tld zmail.ru -util_rb_2tld t35.net -util_rb_2tld t35.com -util_rb_2tld wordpress.com -util_rb_2tld jino-net.ru -util_rb_2tld 6a.org -util_rb_2tld xf.cz -util_rb_2tld fr.tc -util_rb_2tld googlegroups.com -util_rb_2tld 150m.com -util_rb_2tld bravepages.com -util_rb_2tld ucoz.ru -util_rb_2tld ucoz.com -util_rb_2tld ucoz.net -util_rb_2tld szm.com -util_rb_2tld geocities.jp -util_rb_2tld gmxhome.de -util_rb_2tld freeservercity.com -util_rb_2tld iquebec.com -util_rb_2tld mail2k.ru -util_rb_2tld mail.ru -util_rb_2tld ath.cx -util_rb_2tld go.ro -util_rb_2tld z8.ru -util_rb_2tld appspot.com -util_rb_2tld gigazu.net -util_rb_2tld weebly.com -util_rb_2tld ifrance.com -util_rb_2tld jimdo.com -util_rb_2tld kimsufi.com -util_rb_2tld mail333.su -util_rb_2tld pisem.su -util_rb_2tld mail15.su -util_rb_2tld prserv.net -util_rb_2tld angelfire.com -util_rb_2tld 163.to -util_rb_2tld home.pl -util_rb_2tld redirectme.net -util_rb_2tld interia.pl -util_rb_2tld co.kg -util_rb_2tld ning.com -util_rb_2tld xorg.pl -util_rb_2tld free.fr -util_rb_2tld we.bs -util_rb_2tld net.tc -util_rb_2tld isuisse.com -util_rb_2tld de.ki -util_rb_2tld funpic.de -util_rb_2tld interii.pl -util_rb_2tld selfip.com -#util_rb_2tld livejournal.com - Removed per bug 6662 4/7/15 - KAM -util_rb_2tld t3.to -util_rb_2tld fx.to -util_rb_2tld iespana.es -util_rb_2tld go.com -util_rb_2tld hostevo.com -util_rb_2tld iwebsource.com -util_rb_2tld one.pl -util_rb_2tld gratishost.com -util_rb_2tld netfirms.com -util_rb_2tld ibelgique.com -util_rb_2tld to.it -util_rb_2tld whsites.net -util_rb_2tld home.ro -util_rb_2tld 1blu.de -util_rb_2tld co.cc -util_rb_2tld cc.cc -util_rb_2tld webs.com -util_rb_2tld webcindario.com -util_rb_2tld idoo.com -util_rb_2tld selfip.net -util_rb_2tld ovh.net -util_rb_2tld sapo.pt -util_rb_2tld homeip.net -util_rb_2tld unlugar.com -util_rb_2tld nov.ru -util_rb_2tld republika.pl -util_rb_2tld blog.com -util_rb_2tld sosblog.com -util_rb_2tld servebbs.com -util_rb_2tld serveftp.com -util_rb_2tld gob.ve -util_rb_2tld xanga.com -util_rb_2tld com.vc -util_rb_2tld net.vc -util_rb_2tld org.vc -util_rb_2tld kickme.to -util_rb_2tld asso.ws -util_rb_2tld url.st -util_rb_2tld at.pn -util_rb_2tld au.pn -util_rb_2tld ca.pn -util_rb_2tld ch.pn -util_rb_2tld cn.pn -util_rb_2tld co.pn -util_rb_2tld corp.st -util_rb_2tld societe.st -util_rb_2tld de.pn -util_rb_2tld es.pn -util_rb_2tld eu.pn -util_rb_2tld euro.tm -util_rb_2tld fr.pn -util_rb_2tld gov.pn -util_rb_2tld government.pn -util_rb_2tld it.pn -util_rb_2tld jp.pn -util_rb_2tld perso.tc -util_rb_2tld site.tc -util_rb_2tld societe.st -util_rb_2tld url.st -util_rb_2tld blog.ru -util_rb_2tld eu.tc -util_rb_2tld us.tc -util_rb_2tld pro.tc -util_rb_2tld de.tc -util_rb_2tld at.tc -util_rb_2tld it.tc -util_rb_2tld es.tc -util_rb_2tld ru.tc -util_rb_2tld se.tc -util_rb_2tld dk.tc -util_rb_2tld be.tc -util_rb_2tld no.tc -util_rb_2tld int.tc -util_rb_2tld pl.tc -util_rb_2tld bg.tc -util_rb_2tld cz.tc -util_rb_2tld mx.tc -util_rb_2tld br.tc -util_rb_2tld hk.tc -util_rb_2tld kr.tc -util_rb_2tld th.tc -util_rb_2tld ph.tc -util_rb_2tld at.lv -util_rb_2tld de.lv -util_rb_2tld ch.lv -util_rb_2tld org.rw -util_rb_2tld myvnc.com -util_rb_2tld blog4ever.com -util_rb_2tld sytes.net -util_rb_2tld multiply.com -util_rb_2tld 80.hk -util_rb_2tld shutterfly.com -util_rb_2tld chez.com -util_rb_2tld ce.ms -util_rb_2tld zapto.org -util_rb_2tld cz.cc -util_rb_2tld fromru.su -util_rb_2tld krovatka.su -util_rb_2tld pochta.com -util_rb_2tld 5ballov.ru -util_rb_2tld usa.cc -util_rb_2tld jpn.com -util_rb_2tld yolasite.com -util_rb_2tld in.net -util_rb_2tld com.de -util_rb_2tld biz.ua -util_rb_2tld azurewebsites.net -util_rb_2tld azureedge.net -util_rb_2tld zohosites.com -util_rb_2tld wixsite.com -util_rb_2tld firebaseapp.com -util_rb_2tld web.app -# -util_rb_2tld neostrada.pl -util_rb_2tld vv.cc -util_rb_2tld co.be -util_rb_2tld uni.cc -util_rb_2tld shop.co -util_rb_2tld tumblr.com -util_rb_2tld fileave.com -util_rb_2tld de.tl -util_rb_2tld co.com -# Dyndns.com -util_rb_2tld dyndns-at-home.com -util_rb_2tld dyndns-at-work.com -util_rb_2tld dyndns-blog.com -util_rb_2tld dyndns-free.com -util_rb_2tld dyndns-home.com -util_rb_2tld dyndns-ip.com -util_rb_2tld dyndns-mail.com -util_rb_2tld dyndns-office.com -util_rb_2tld dyndns-pics.com -util_rb_2tld dyndns-remote.com -util_rb_2tld dyndns-server.com -util_rb_2tld dyndns-web.com -util_rb_2tld dyndns-wiki.com -util_rb_2tld dyndns-work.com -util_rb_2tld dyndns.biz -util_rb_2tld dyndns.info -util_rb_2tld dyndns.org -util_rb_2tld dyndns.tv -util_rb_2tld dyndns.dk -util_rb_2tld dyndns.ws -util_rb_2tld mydyndns.org -util_rb_2tld qip.ru -# -util_rb_2tld no-ip.biz -util_rb_2tld no-ip.ca -util_rb_2tld no-ip.com -util_rb_2tld no-ip.info -util_rb_2tld no-ip.net -util_rb_2tld no-ip.org -# -util_rb_2tld gotdns.ch -util_rb_2tld ddnsking.com -util_rb_2tld ddns.net -util_rb_2tld bounceme.net -util_rb_2tld hopto.org -util_rb_2tld serveblog.net -util_rb_2tld myftp.org -util_rb_2tld myftp.biz - - -# -# 3rd level TLD list (SA 3.3+) -# -# There was a bug before 3.4.1(?), only one 3TLD per line works! -# - -if (version >= 3.003000) - -util_rb_3tld demon.co.uk -util_rb_3tld esc.edu.ar -util_rb_3tld lkd.co.im -util_rb_3tld plc.co.im -util_rb_3tld ltd.co.im -# -util_rb_3tld bay.livefilestore.com -util_rb_3tld blu.livefilestore.com -util_rb_3tld groups.live.com -util_rb_3tld spaces.live.com -util_rb_3tld profile.live.com -util_rb_3tld web.aplus.net -util_rb_3tld cloud.prohosting.com -util_rb_3tld skydrive.live.com -util_rb_3tld docs.google.com -util_rb_3tld spaces.msn.com -util_rb_3tld blog.friendster.com -util_rb_3tld plc.co.im -util_rb_3tld ltd.co.im -util_rb_3tld sakura.ne.jp -util_rb_3tld web.officelive.com -util_rb_3tld com.sapo.pt -util_rb_3tld paginas.sapo.pt -util_rb_3tld no.sapo.pt -util_rb_3tld home.sapo.pt -util_rb_3tld do.sapo.pt -util_rb_3tld homepage.t-online.de -util_rb_3tld privat.t-online.de -util_rb_3tld web.fc2.com -util_rb_3tld co.uk.pn -util_rb_3tld com.au.pn -util_rb_3tld co.at.pn -util_rb_3tld co.at.lv -util_rb_3tld or.at.lv -util_rb_3tld co.at.tc -util_rb_3tld qld.edu.au -util_rb_3tld perso.neuf.fr -util_rb_3tld perso.sfr.fr -util_rb_3tld hop.clickbank.net -util_rb_3tld user.icpnet.pl -util_rb_3tld en.alibaba.com -# -util_rb_3tld blogspot.co.nz -util_rb_3tld blogspot.co.uk -util_rb_3tld blogspot.com.ar -util_rb_3tld blogspot.com.au -util_rb_3tld blogspot.com.br -util_rb_3tld blogspot.com.es -# -util_rb_3tld no-ip.co.uk -# -util_rb_3tld mobile.web.tr -util_rb_3tld ct.sendgrid.net - -endif - - diff --git a/resources/spamassassin/20_body_tests.cf b/resources/spamassassin/20_body_tests.cf deleted file mode 100644 index 55223a53..00000000 --- a/resources/spamassassin/20_body_tests.cf +++ /dev/null @@ -1,169 +0,0 @@ -# SpamAssassin rules file: body tests -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# Note: body tests are run with long lines, so be sure to limit the -# size of searches; use /.{0,30}/ instead of /.*/ to avoid huge -# search times. -# -# Note: If you are adding a rule which looks for a phrase in the body -# (as most of them do), please add it to rules/20_phrases.cf instead. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -########################################################################### -# GTUBE test - the generic test for UBE. -body GTUBE /XJS\*C4JDBQADN1\.NSBN3\*2IDNEN\*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL\*C\.34X/ -describe GTUBE Generic Test for Unsolicited Bulk Email -tflags GTUBE userconf noautolearn - -########################################################################### - -# this seems to be the new fashion (as of Jul 5 2002). base64-encoded -# parts need to be stripped before this match -body TRACKER_ID /^[a-z0-9]{6,24}[-_a-z0-9]{12,36}[a-z0-9]{6,24}\s*\z/is -describe TRACKER_ID Incorporates a tracking ID number - -body WEIRD_QUOTING /[\042\223\224\262\263\271]{2}\S{0,16}[\042\223\224\262\263\271]{2}/ -describe WEIRD_QUOTING Weird repeated double-quotation marks - -########################################################################### -# multipart/alternative has very good accuracy, other multipart types are -# similar to MIME_HTML_ONLY so they don't need a separate rule -header __CTYPE_MULTIPART_ALT Content-Type =~ /multipart\/alternative/i -meta MIME_HTML_ONLY_MULTI (__CTYPE_MULTIPART_ALT && MIME_HTML_ONLY) -describe MIME_HTML_ONLY_MULTI Multipart message only has text/html MIME parts - -# note: __HIGHBITS is used in rules/20_html_tests.cf, HTML_CHARSET_FARAWAY -meta MIME_CHARSET_FARAWAY (__MIME_CHARSET_FARAWAY && __HIGHBITS) -describe MIME_CHARSET_FARAWAY MIME character set indicates foreign language -tflags MIME_CHARSET_FARAWAY userconf - -########################################################################### - -# duncf -body EMAIL_ROT13 /\b[a-z(\]-]+\^[a-z-]+\([a-z]{2,3}\b/ -describe EMAIL_ROT13 Body contains a ROT13-encoded email address -test EMAIL_ROT13 ok qhabs^ebtref(pbz -test EMAIL_ROT13 ok zxrggyre^riv-vap(pbz -test EMAIL_ROT13 fail duncf-nospam@rogers.com - -# this could use more work -body __LONGWORDS_A /\b(?:[a-z]{8,}[\s\.]+){6}/ -body __LONGWORDS_B /\b(?:[a-z]{6,}[\s\.]+){9}/ -body __LONGWORDS_C /\b(?:[a-z]{5,}[\s\.]+){10}/ -meta LONGWORDS (__LONGWORDS_A + __LONGWORDS_B + __LONGWORDS_C > 1) -describe LONGWORDS Long string of long words - - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - - -# This rule uses a simple algorithm to determine if the text and html -# parts of an multipart/alternative message are different. -body MPART_ALT_DIFF eval:multipart_alternative_difference('99', '100') -describe MPART_ALT_DIFF HTML and text parts are different - -body MPART_ALT_DIFF_COUNT eval:multipart_alternative_difference_count('3', '1') -describe MPART_ALT_DIFF_COUNT HTML and text parts are different - -body BLANK_LINES_80_90 eval:check_blank_line_ratio('80','90','4') -describe BLANK_LINES_80_90 Message body has 80-90% blank lines - -# it's the ratio of spaces to non-spaces in each paragraph. apparently -# messages where generally there are lots of spaces mean the message is spam. -# 8.532 10.6051 0.1897 0.982 0.75 0.01 T_VERTICAL_WORDS_TVD_1 -# bug 6149: avoid common .jp false positives -header __SUBJECT_UTF8_B_ENCODED Subject:raw =~ /=\?UTF-?8\?B\?/i -body __TVD_SPACE_RATIO eval:tvd_vertical_words('0','10') -meta TVD_SPACE_RATIO (__TVD_SPACE_RATIO && !__ISO_2022_JP_DELIM && !__SUBJECT_UTF8_B_ENCODED && !__HIGHBITS) - -endif - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - -# 0.767 0.9097 0.0000 1.000 0.84 1.00 MULTIPART_ALT_NON_TEXT -body MULTIPART_ALT_NON_TEXT eval:check_ma_non_text() - -body CHARSET_FARAWAY eval:check_for_faraway_charset() -describe CHARSET_FARAWAY Character set indicates a foreign language -tflags CHARSET_FARAWAY userconf - -# these tests doesn't actually use rawbody since rawbody isn't raw enough; -# they must be written very carefully to avoid modifying the original content - -# MIME Content-Transfer-Encoding control rules -rawbody __MIME_BASE64 eval:check_for_mime('mime_base64_count') -describe __MIME_BASE64 Includes a base64 attachment - -rawbody __MIME_QP eval:check_for_mime('mime_qp_count') -describe __MIME_QP Includes a quoted-printable attachment - -# No longer used in MIMEEval -#rawbody MIME_BASE64_BLANKS eval:check_for_mime('mime_base64_blanks') -#describe MIME_BASE64_BLANKS Extra blank lines in base64 encoding - - -rawbody MIME_BASE64_TEXT eval:check_for_mime('mime_base64_encoded_text') -describe MIME_BASE64_TEXT Message text disguised using base64 encoding - - -body MISSING_MIME_HB_SEP eval:check_msg_parse_flags('missing_mime_head_body_separator') -describe MISSING_MIME_HB_SEP Missing blank line between MIME header and body - -body MIME_HTML_MOSTLY eval:check_mime_multipart_ratio('0.00','0.01') -describe MIME_HTML_MOSTLY Multipart message mostly text/html MIME - -# Steve Linford via Charlie Watts: good test! -body MIME_HTML_ONLY eval:check_for_mime_html_only() -describe MIME_HTML_ONLY Message only has text/html MIME parts - -rawbody MIME_QP_LONG_LINE eval:check_for_mime('mime_qp_long_line') -describe MIME_QP_LONG_LINE Quoted-printable line longer than 76 chars - -rawbody __MIME_CHARSET_FARAWAY eval:check_for_mime('mime_faraway_charset') - -body MIME_BAD_ISO_CHARSET eval:check_for_mime('mime_bad_iso_charset') -describe MIME_BAD_ISO_CHARSET MIME character set is an unknown ISO charset - -body MIMEPART_LIMIT_EXCEEDED eval:check_for_mime('mimepart_limit_exceeded') -describe MIMEPART_LIMIT_EXCEEDED Message has too many MIME parts - -endif - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::URIEval - -body HTTPS_IP_MISMATCH eval:check_https_ip_mismatch() -describe HTTPS_IP_MISMATCH IP to HTTPS link found in HTML - -body URI_TRUNCATED eval:check_uri_truncated() -describe URI_TRUNCATED Message contained a URI which was truncated - -endif diff --git a/resources/spamassassin/20_compensate.cf b/resources/spamassassin/20_compensate.cf deleted file mode 100644 index f7f62a8b..00000000 --- a/resources/spamassassin/20_compensate.cf +++ /dev/null @@ -1,48 +0,0 @@ -# SpamAssassin rules file: compensation for common false positives -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### -# Header compensation tests - -require_version @@VERSION@@ - -header __HAS_RCVD exists:Received -priority __HAS_RCVD -2000 # Bug 8078 -meta NO_RECEIVED (!__HAS_RCVD) -tflags NO_RECEIVED nice userconf -describe NO_RECEIVED Informational: message has no Received headers - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::RelayEval - -# The message was never sent via an untrustworthy host. -header ALL_TRUSTED eval:check_all_trusted() -describe ALL_TRUSTED Passed through trusted hosts only via SMTP -tflags ALL_TRUSTED nice userconf - -header NO_RELAYS eval:check_no_relays() -tflags NO_RELAYS nice userconf -describe NO_RELAYS Informational: message was not relayed via SMTP - -endif diff --git a/resources/spamassassin/20_dnsbl_tests.cf b/resources/spamassassin/20_dnsbl_tests.cf deleted file mode 100644 index 93e7356e..00000000 --- a/resources/spamassassin/20_dnsbl_tests.cf +++ /dev/null @@ -1,251 +0,0 @@ -# SpamAssassin rules file: DNS blocklist and welcomelist tests -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::DNSEval - -# See the Mail::SpamAssassin::Conf manual page for details of how to use -# check_rbl(). - -# --------------------------------------------------------------------------- -# Multizone / Multi meaning BLs first. -# -# Note that currently TXT queries cannot be used for these, since the -# DNSBLs do not return the A type (127.0.0.x) as part of the TXT reply. - - -# --------------------------------------------------------------------------- -# SORBS -# transfers: both axfr and ixfr available -# URL: http://www.dnsbl.sorbs.net/ -# pay-to-use: no -# delist: $50 fee for RCVD_IN_SORBS_SPAM, others have free retest on request - -header __RCVD_IN_SORBS eval:check_rbl('sorbs', 'dnsbl.sorbs.net.') -describe __RCVD_IN_SORBS SORBS: sender is listed in SORBS -tflags __RCVD_IN_SORBS net -reuse __RCVD_IN_SORBS - -header RCVD_IN_SORBS_HTTP eval:check_rbl_sub('sorbs', '127.0.0.2') -describe RCVD_IN_SORBS_HTTP SORBS: sender is open HTTP proxy server -tflags RCVD_IN_SORBS_HTTP net -reuse RCVD_IN_SORBS_HTTP - -header RCVD_IN_SORBS_SOCKS eval:check_rbl_sub('sorbs', '127.0.0.3') -describe RCVD_IN_SORBS_SOCKS SORBS: sender is open SOCKS proxy server -tflags RCVD_IN_SORBS_SOCKS net -reuse RCVD_IN_SORBS_SOCKS - -header RCVD_IN_SORBS_MISC eval:check_rbl_sub('sorbs', '127.0.0.4') -describe RCVD_IN_SORBS_MISC SORBS: sender is open proxy server -tflags RCVD_IN_SORBS_MISC net -reuse RCVD_IN_SORBS_MISC - -header RCVD_IN_SORBS_SMTP eval:check_rbl_sub('sorbs', '127.0.0.5') -describe RCVD_IN_SORBS_SMTP SORBS: sender is open SMTP relay -tflags RCVD_IN_SORBS_SMTP net -reuse RCVD_IN_SORBS_SMTP - -# delist: $50 fee -#header RCVD_IN_SORBS_SPAM eval:check_rbl_sub('sorbs', '127.0.0.6') -#describe RCVD_IN_SORBS_SPAM SORBS: sender is a spam source -#tflags RCVD_IN_SORBS_SPAM net -#reuse RCVD_IN_SORBS_SPAM RCVD_IN_SORBS_SPAM - -header RCVD_IN_SORBS_WEB eval:check_rbl_sub('sorbs', '127.0.0.7') -describe RCVD_IN_SORBS_WEB SORBS: sender is an abusable web server -tflags RCVD_IN_SORBS_WEB net -reuse RCVD_IN_SORBS_WEB - -header RCVD_IN_SORBS_BLOCK eval:check_rbl_sub('sorbs', '127.0.0.8') -describe RCVD_IN_SORBS_BLOCK SORBS: sender demands to never be tested -tflags RCVD_IN_SORBS_BLOCK net -reuse RCVD_IN_SORBS_BLOCK - -header RCVD_IN_SORBS_ZOMBIE eval:check_rbl_sub('sorbs', '127.0.0.9') -describe RCVD_IN_SORBS_ZOMBIE SORBS: sender is on a hijacked network -tflags RCVD_IN_SORBS_ZOMBIE net -reuse RCVD_IN_SORBS_ZOMBIE - -header RCVD_IN_SORBS_DUL eval:check_rbl('sorbs-lastexternal', 'dnsbl.sorbs.net.', '127.0.0.10') -describe RCVD_IN_SORBS_DUL SORBS: sent directly from dynamic IP address -tflags RCVD_IN_SORBS_DUL net -reuse RCVD_IN_SORBS_DUL - -# --------------------------------------------------------------------------- -# Spamhaus ZEN includes SBL+CSS+XBL+PBL -# https://www.spamhaus.org/faq/section/DNSBL%20Usage#200 -# -# Spamhaus XBL contains the Abuseat CBL data (cbl.abuseat.org) - -header __RCVD_IN_ZEN eval:check_rbl('zen', 'zen.spamhaus.org.') -describe __RCVD_IN_ZEN Received via a relay in Spamhaus Zen -tflags __RCVD_IN_ZEN net -reuse __RCVD_IN_ZEN - -# SBL is the Spamhaus Block List: https://www.spamhaus.org/sbl/ -header RCVD_IN_SBL eval:check_rbl_sub('zen', '127.0.0.2') -describe RCVD_IN_SBL Received via a relay in Spamhaus SBL -tflags RCVD_IN_SBL net -reuse RCVD_IN_SBL - -# XBL is the Exploits Block List: https://www.spamhaus.org/xbl/ -header RCVD_IN_XBL eval:check_rbl('zen-lastexternal', 'zen.spamhaus.org.', '^127\.0\.0\.[4567]$') -describe RCVD_IN_XBL Received via a relay in Spamhaus XBL -tflags RCVD_IN_XBL net -reuse RCVD_IN_XBL - -# PBL is the Policy Block List: https://www.spamhaus.org/pbl/ -header RCVD_IN_PBL eval:check_rbl('zen-lastexternal', 'zen.spamhaus.org.', '^127\.0\.0\.1[01]$') -describe RCVD_IN_PBL Received via a relay in Spamhaus PBL -tflags RCVD_IN_PBL net -reuse RCVD_IN_PBL - -# CSS is the Spamhaus CSS Component of the SBL List: https://www.spamhaus.org/css/ -header RCVD_IN_SBL_CSS eval:check_rbl_sub('zen', '127.0.0.3') -describe RCVD_IN_SBL_CSS Received via a relay in Spamhaus SBL-CSS -tflags RCVD_IN_SBL_CSS net -reuse RCVD_IN_SBL_CSS - -# New blocked checks 10/2019 -header RCVD_IN_ZEN_BLOCKED_OPENDNS eval:check_rbl('zen-lastexternal', 'zen.spamhaus.org.', '^127\.255\.255\.254$') -describe RCVD_IN_ZEN_BLOCKED_OPENDNS ADMINISTRATOR NOTICE: The query to zen.spamhaus.org was blocked due to usage of an open resolver. See https://www.spamhaus.org/returnc/pub/ -tflags RCVD_IN_ZEN_BLOCKED_OPENDNS net -reuse RCVD_IN_ZEN_BLOCKED_OPENDNS - -# New blocked checks 10/2019 -header RCVD_IN_ZEN_BLOCKED eval:check_rbl('zen-lastexternal', 'zen.spamhaus.org.', '^127\.255\.255\.255$') -describe RCVD_IN_ZEN_BLOCKED ADMINISTRATOR NOTICE: The query to zen.spamhaus.org was blocked. See https://www.spamhaus.org/returnc/vol/ -tflags RCVD_IN_ZEN_BLOCKED net -reuse RCVD_IN_ZEN_BLOCKED - -if can(Mail::SpamAssassin::Conf::feature_dns_block_rule) -dns_block_rule RCVD_IN_ZEN_BLOCKED_OPENDNS zen.spamhaus.org -dns_block_rule RCVD_IN_ZEN_BLOCKED zen.spamhaus.org -endif - - -# Now, single zone BLs follow: - -# --------------------------------------------------------------------------- -# NOTE: donation tests, see README file for details - -header RCVD_IN_BL_SPAMCOP_NET eval:check_rbl_txt('spamcop', 'bl.spamcop.net.', '(?i:spamcop)') -describe RCVD_IN_BL_SPAMCOP_NET Received via a relay in bl.spamcop.net -tflags RCVD_IN_BL_SPAMCOP_NET net -reuse RCVD_IN_BL_SPAMCOP_NET - -# --------------------------------------------------------------------------- -# NOTE: commercial tests, see README file for details - -header RCVD_IN_MAPS_RBL eval:check_rbl('rblplus', 'activationcode.r.mail-abuse.com.', '1') -describe RCVD_IN_MAPS_RBL Relay in RBL, http://www.mail-abuse.com/enduserinfo_rbl.html -tflags RCVD_IN_MAPS_RBL net -reuse RCVD_IN_MAPS_RBL - -header RCVD_IN_MAPS_DUL eval:check_rbl('rblplus-lastexternal', 'activationcode.r.mail-abuse.com.', '2') -describe RCVD_IN_MAPS_DUL Relay in DUL, http://www.mail-abuse.com/enduserinfo_dul.html -tflags RCVD_IN_MAPS_DUL net -reuse RCVD_IN_MAPS_DUL - -header RCVD_IN_MAPS_RSS eval:check_rbl_sub('rblplus', '4') -describe RCVD_IN_MAPS_RSS Relay in RSS, http://www.mail-abuse.com/enduserinfo_rss.html -tflags RCVD_IN_MAPS_RSS net -reuse RCVD_IN_MAPS_RSS - -header RCVD_IN_MAPS_OPS eval:check_rbl_sub('rblplus', '8') -describe RCVD_IN_MAPS_OPS Relay in OPS, http://www.mail-abuse.com/enduserinfo_ops.html -tflags RCVD_IN_MAPS_OPS net -reuse RCVD_IN_MAPS_OPS - -# The NML isn't part of the RBL+ and I find any documentation for it - is it dead? -header RCVD_IN_MAPS_NML eval:check_rbl('nml', 'nonconfirm.mail-abuse.com.') -describe RCVD_IN_MAPS_NML Relay in NML, http://www.mail-abuse.com/enduserinfo_nml.html -tflags RCVD_IN_MAPS_NML net -reuse RCVD_IN_MAPS_NML - -# --------------------------------------------------------------------------- -# Section for DNS WL related lookups below. - -# IADB support ... -header __RCVD_IN_IADB eval:check_rbl('iadb-firsttrusted', 'iadb.isipp.com.') -tflags __RCVD_IN_IADB net nice -reuse __RCVD_IN_IADB - -header RCVD_IN_IADB_VOUCHED eval:check_rbl_sub('iadb-firsttrusted', '127.0.1.255') -describe RCVD_IN_IADB_VOUCHED ISIPP IADB lists as vouched-for sender -tflags RCVD_IN_IADB_VOUCHED net nice -reuse RCVD_IN_IADB_VOUCHED - -# --------------------------------------------------------------------------- -# Validity (née Return Path, SenderScore) reputation DNSBLs -# https://issues.apache.org/SpamAssassin/show_bug.cgi?id=6247 -# Certified: -# https://www.validity.com/resource-center/fact-sheet-certification/ -# (replaces RCVD_IN_BSP_TRUSTED, RCVD_IN_BSP_OTHER, RCVD_IN_SSC_TRUSTED_COI, RCVD_IN_RP_CERTIFIED) -header RCVD_IN_VALIDITY_CERTIFIED eval:check_rbl_txt('ssc-firsttrusted', 'sa-trusted.bondedsender.org.') -describe RCVD_IN_VALIDITY_CERTIFIED Sender in Validity Certification - Contact certification@validity.com -tflags RCVD_IN_VALIDITY_CERTIFIED net nice publish -reuse RCVD_IN_VALIDITY_CERTIFIED RCVD_IN_RP_CERTIFIED - -# Safe: -# https://www.validity.com/resource-center/fact-sheet-certification/ -# (replaces HABEAS_ACCREDITED_COI, HABEAS_ACCREDITED_SOI, HABEAS_CHECKED, RCVD_IN_RP_SAFE) -header RCVD_IN_VALIDITY_SAFE eval:check_rbl_txt('ssc-firsttrusted','sa-accredit.habeas.com.') -describe RCVD_IN_VALIDITY_SAFE Sender in Validity Safe - Contact certification@validity.com -tflags RCVD_IN_VALIDITY_SAFE net nice publish -reuse RCVD_IN_VALIDITY_SAFE RCVD_IN_RP_SAFE - -# Validity RPBL (née Return Path Reputation Network Blacklist - RNBL): -# https://www.senderscore.org/blocklistlookup/ -# (replaces RCVD_IN_RP_RNBL) -header RCVD_IN_VALIDITY_RPBL eval:check_rbl('rnbl-lastexternal','bl.score.senderscore.com.') -describe RCVD_IN_VALIDITY_RPBL Relay in Validity RPBL, https://senderscore.org/blocklistlookup/ -tflags RCVD_IN_VALIDITY_RPBL net publish -reuse RCVD_IN_VALIDITY_RPBL RCVD_IN_RP_RNBL - -endif - -#These are old and useless - The zones are no longer supported by SpamHaus 2018-12-12 -#ifplugin Mail::SpamAssassin::Plugin::AskDNS -# -#askdns DKIMDOMAIN_IN_DWL _DKIMDOMAIN_._vouch.dwl.spamhaus.org TXT /^([a-z]+ )*(transaction|list|all)( [a-z]+)*$/ -#tflags DKIMDOMAIN_IN_DWL net nice -#describe DKIMDOMAIN_IN_DWL Signing domain listed in Spamhaus DWL -#reuse DKIMDOMAIN_IN_DWL -# -#askdns __DKIMDOMAIN_IN_DWL_ANY _DKIMDOMAIN_._vouch.dwl.spamhaus.org TXT -#tflags __DKIMDOMAIN_IN_DWL_ANY net nice -#describe __DKIMDOMAIN_IN_DWL_ANY Any TXT response received from a Spamhaus DWL -#reuse __DKIMDOMAIN_IN_DWL_ANY -# -#meta DKIMDOMAIN_IN_DWL_UNKNOWN __DKIMDOMAIN_IN_DWL_ANY && !DKIMDOMAIN_IN_DWL -#tflags DKIMDOMAIN_IN_DWL_UNKNOWN net nice -#describe DKIMDOMAIN_IN_DWL_UNKNOWN Unrecognized response from Spamhaus DWL -# -#endif diff --git a/resources/spamassassin/20_drugs.cf b/resources/spamassassin/20_drugs.cf deleted file mode 100644 index 94d59c8c..00000000 --- a/resources/spamassassin/20_drugs.cf +++ /dev/null @@ -1,277 +0,0 @@ -# SpamAssassin rules file: drug tests -# -# This ruleset is intended to detect common "pill spam" however, it is not -# appropriate for all environments. It may not be appropriate for a medical or -# pharmaceutical environment. If in doubt, adjust the scores of all the rules -# to 0.01 and see if they fire off on your daily nonspam. -# -# Please don't modify this file as your changes will be overwritten with the -# next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. See 'perldoc -# Mail::SpamAssassin::Conf' for details. -# -# Note: body tests are run with long lines, so be sure to limit the size of -# searches; use /.{0,30}/ instead of /.*/ to avoid huge search times. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -########################################################################### -# header rules -# (only use sufficiently long drug name to make name unique) - -header SUBJECT_DRUG_GAP_C Subject =~ /\bc(?!ialis(?:t|\xc3\xa9|\xe9))[\sc]{0,2}i[\si]{0,2}a[\sa]{0,2}l[\sl]{0,2}i[\si]{0,2}s{1,3}\b/i -describe SUBJECT_DRUG_GAP_C Subject contains a gappy version of 'cialis' - -header SUBJECT_DRUG_GAP_L Subject =~ /l.{0,2}e.{0,2}v.{0,2}i.{0,2}t.{0,2}r.{0,2}a/i -describe SUBJECT_DRUG_GAP_L Subject contains a gappy version of 'levitra' - - -header SUBJECT_DRUG_GAP_S Subject =~ /\bs.{0,1}o.{0,1}m.{0,1}a\b/i -describe SUBJECT_DRUG_GAP_S Subject contains a gappy version of 'soma' - -# Bug 5396 - Hits visa and random finnish words -#header SUBJECT_DRUG_GAP_VA Subject =~ /v.{0,2}a.{0,2}l.{0,2}i.{0,2}u.{0,2}m/i -#describe SUBJECT_DRUG_GAP_VA Subject contains a gappy version of 'valium' - - -header SUBJECT_DRUG_GAP_X Subject =~ /x.{0,2}a.{0,2}n.{0,2}a.{0,2}x/i -describe SUBJECT_DRUG_GAP_X Subject contains a gappy version of 'xanax' - -########################################################################### -# body rules - -body DRUG_DOSAGE m{[\d\.]+ *\$? *(?:[\\/]|per) *d.?o.?s.?e}i -describe DRUG_DOSAGE Talks about price per dose - -# jm: keep this case-sensitive, otherwise it FP's -body DRUG_ED_CAPS /\b(?:CIALIS|LEVITRA|VIAGRA)/ -describe DRUG_ED_CAPS Mentions an E.D. drug - - -body DRUG_ED_SILD /\bsildenafil\b/i -describe DRUG_ED_SILD Talks about an E.D. drug using its chemical name - -body DRUG_ED_GENERIC /\bGeneric Viagra\b/ -describe DRUG_ED_GENERIC Mentions Generic Viagra - -body DRUG_ED_ONLINE /\bviagra .{0,25}(?:express|online|overnight)/i -describe DRUG_ED_ONLINE Fast Viagra Delivery - -body ONLINE_PHARMACY /\bonline pharmacy|\b(?:drugs|medications) online/i -describe ONLINE_PHARMACY Online Pharmacy - -# Updated bug 6448 -body NO_PRESCRIPTION /N[o0].{1,10}P(?:er|re)scr[i1]pt[i1][o0]n.{1,10}(?:n[e3][e3]d[e3]d|requ[1i]re|n[e3]c[e3]ssary)/i -describe NO_PRESCRIPTION No prescription needed - -# too easy -body VIA_GAP_GRA /\bvia.gra\b/i -describe VIA_GAP_GRA Attempts to disguise the word 'viagra' - -######################################################################## -# male sexual dysfunction drugs -# -# This section is undergoing improvements and I'm trying to track down a -# FP case that seems to mostly affect technical emails. -# However, all of the test cases so far fail to match when retested. -# note: The regex /v.i.a.g.r.a/ was intentionally not used -# due to potential false positive cases with PGP signatures -# and other base-64ish stuff. -# instead other patterns are used catch non alphanumeric gapping patterns -# note: \W = "non word character" - -# Note: many of the drugs named in here are brand-names and are trademarked. -# All trademarks are property of the respective owners. -#current best char substitutions -# i - [i1!|l\xEC-\xEF] -# a - [a4\xE0-\xE6@] -# e - [e3\xE8-\xEB] -# o - [o0\xF2-\xF6] -# u - [u\xB5\xF9-\xFC] - -# v - (?:\\\/|V) -# l - [l!|1] -# -# Also see 25_replace.cf -# -# If you're adding accented-character exclusions, include the HTML entity tags -# as well to cover the case where they appear in plain-text body parts. -# -#plain Viagra and Cialis (used in obfu detection) -body __DRUGS_ERECTILE_V /\bViagra\b/i -body __DRUGS_ERECTILE_C /\bCialis(?!\xc3\xa9|\xe9)\b/i -body __DRUGS_ERECTILE_L /\bLevitra\b/i -# obfu/plain and mis-spelled Viagra variants -body __DRUGS_ERECTILE1 /(?:\b|\s)[_\W]{0,3}(?:\\\/|V)[_\W]{0,3}[ij1!|l\xEC\xED\xEE\xEF][_\W]{0,3}[a40\xE0-\xE6@][_\W]{0,3}[xyz]?[gj][_\W]{0,3}r[_\W]{0,3}[a40\xE0-\xE6@][_\W]{0,3}x?[_\W]{0,3}(?:\b|\s)/i -body __DRUGS_ERECTILE2 /\bV(?:agira|igara|iaggra|iaegra)\b/i -# cialis variants (spelling correct now) -# note: the rather strange pre-amble is to avoid FPs on french words containing high-ascii chars surrounding -# "cialis". -# try to avoid FPs on "specialist" and FR "spécialisé" -body __DRUGS_ERECTILE3 /(?:\A|[\s\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])[_\W]{0,3}(?!cialis(?:t|\xc3\xa9|\xe9|\&\#xe9\;|\é\;)|c i a l i s (?:t|\xc3\xa9|\xe9|\&\#xe9\;|\é\;))C[_\W]{0,3}[ij1!|l\xEC\xED\xEE\xEF][_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}l?[l!|1][_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}s[_\W]{0,3}(?:\b|\s)/i -body __DRUGS_ERECTILE4 /\bC(?:alis|ilias|ilais)\b/i -# generic names -#sildenafil citrate -body __DRUGS_ERECTILE5 /\b_{0,3}s[_\W]?[i1!|l\xEC-\xEF][_\W]?l[_\W]?d[_\W]?[e3\xE8-\xEB][_\W]?n[_\W]?[a4\xE0-\xE6@][_\W]?f[_\W]?[i1!|l\xEC-\xEF][_\W]?l c[_\W]?[i1!|l\xEC-\xEF][_\W]?t[_\W]?r[_\W]?[a4\xE0-\xE6@][_\W]?t[_\W]?[e3\xE8-\xEB]_{0,3}(?:\b|\s)/i -#Levitra -body __DRUGS_ERECTILE6 /\b_{0,3}L[_\W]?[e3\xE8-\xEB][_\W]?(?:\\\/|V)[_\W]?[i1!|l\xEC-\xEF][_\W]?t[_\W]?r[_\W]?[a4\xE0-\xE6@][_\W]?(?:\b|\s)/i -#tadalafil -body __DRUGS_ERECTILE8 /\b_{0,3}T[_\W]?[a4\xE0-\xE6@][_\W]?d[_\W]?[a4\xE0-\xE6@][_\W]?l[_\W]?[a4\xE0-\xE6@][_\W]?f[_\W]?[i1!|l\xEC-\xEF][_\W]?l_{0,3}\b/i -# gapped/obfu viagra variants using funky html-style character codes -rawbody __DRUGS_ERECTILE10 /\b_{0,3}V[_\W]?(?:i|\ï\;)[_\W]?(?:a|\à|\å)\;?[_\W]?g[_\W]?r[_\W]?(?:a|\à|\å)\b/i -#apcalis - a generic of cialis -body __DRUGS_ERECTILE11 /(?:\b|\s)_{0,3}[a4\xE0-\xE6@][_\W]{0,3}p[_\W]{0,3}c[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}[l!|1][_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}s_{0,3}\b/i -meta DRUGS_ERECTILE (__DRUGS_ERECTILE1 || __DRUGS_ERECTILE2 || __DRUGS_ERECTILE3 || __DRUGS_ERECTILE4 || __DRUGS_ERECTILE5 || __DRUGS_ERECTILE6 || __DRUGS_ERECTILE8 || __DRUGS_ERECTILE10 || __DRUGS_ERECTILE11 ) -describe DRUGS_ERECTILE Refers to an erectile drug -meta DRUGS_ERECTILE_OBFU ( (__DRUGS_ERECTILE1 &&!__DRUGS_ERECTILE_V) || (__DRUGS_ERECTILE3 && !__DRUGS_ERECTILE_C) ||__DRUGS_ERECTILE2 || (__DRUGS_ERECTILE10 &&!__DRUGS_ERECTILE_V) || (__DRUGS_ERECTILE6 &&!__DRUGS_ERECTILE_L)) -describe DRUGS_ERECTILE_OBFU Obfuscated reference to an erectile drug - - - -#diet -body __DRUGS_DIET_PHEN /\bphentermine\b/i -#phentermine -body __DRUGS_DIET1 /(?:\b|\s)[_\W]{0,3}p[_\W]{0,3}h[_\W]{0,3}[e3\xE8-\xEB][_\W]{0,3}n[_\W]{0,3}t[_\W]{0,3}[e3\xE8-\xEB][_\W]{0,3}r[_\W]{0,3}m[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}n[_\W]{0,3}[e3\xE8-\xEB][_\W]{0,3}(?:\b|\s)/i -#ionamin -body __DRUGS_DIET2 /(?:\b|\s)_{0,3}[i1!|l\xEC-\xEF][_\W]?o[_\W]?n[_\W]?[a4\xE0-\xE6@][_\W]?m[_\W]?[i1!|l\xEC-\xEF][_\W]?n_{0,3}\b/i -#bontril -body __DRUGS_DIET3 /\bbontril\b/i -#phendimetrazine -body __DRUGS_DIET4 /\bphendimetrazine\b/i -#diethylpropion, generic of Tenuate, uncommon in spam -body __DRUGS_DIET5 /\bdiethylpropion\b/i -#Meridia -body __DRUGS_DIET6 /(?:\b|\s)[_\W]{0,3}M[_\W]{0,3}[e3\xE8-\xEB][_\W]{0,3}r[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}d[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}(?:\b|\s)/i -#tenuate -body __DRUGS_DIET7 /\b_{0,3}t[_\W]?[e3\xE8-\xEB][_\W]?n[_\W]?u[_\W]?a[_\W]?t[_\W]?[e3\xE8-\xEB]_{0,3}(?:\b|\s)/i -#didrex -body __DRUGS_DIET8 /\b_{0,3}d[_\W]?[i1!|l\xEC-\xEF][_\W]?d[_\W]?r[_\W][e3\xE8-\xEB[_\W]?xx?_{0,3}\b/i -#adipex -body __DRUGS_DIET9 /\b_{0,3}a[_\W]?d[_\W]?[i1!|l\xEC-\xEF][_\W]?p[_\W]?[e3\xE8-\xEB][_\W]?x_{0,3}\b/i -#xenical -body __DRUGS_DIET10 /\b_{0,3}x?x[_\W]?[e3\xE8-\xEB][_\W]?n[_\W]?[i1!|l\xEC-\xEF][_\W]?c[_\W]?[a4\xE0-\xE6@][_\W]?l_{0,3}\b/i -meta DRUGS_DIET (__DRUGS_DIET1 || __DRUGS_DIET2 || __DRUGS_DIET3 || __DRUGS_DIET4 ||__DRUGS_DIET5 ||__DRUGS_DIET6 ||__DRUGS_DIET7 ||__DRUGS_DIET8 || __DRUGS_DIET9 || __DRUGS_DIET10 ) -describe DRUGS_DIET Refers to a diet drug -meta DRUGS_DIET_OBFU (__DRUGS_DIET1 && !__DRUGS_DIET_PHEN) -describe DRUGS_DIET_OBFU Obfuscated reference to a diet drug - -# pain relief drugs -body __DRUGS_PAIN_VICO /vicodin/i -body __DRUGS_PAIN_VIOXX /vioxx/i -body __DRUGS_PAIN_FIO /fioricet/i -body __DRUGS_PAIN1 /\b_{0,3}h[_\W]?y[_\W]?d[_\W]?r[_\W]?[o0\xF2-\xF6][_\W]?c[_\W]?[o0\xF2-\xF6][_\W]?d[_\W]?[o0\xF2-\xF6][_\W]?n[_\W]?e_{0,3}\b/i -body __DRUGS_PAIN2 /\b_{0,3}c[o0\xF2-\xF6]deine_{0,3}\b/i -#ultram -body __DRUGS_PAIN3 /(?:\b|\s)[_\W]{0,3}[u\xB5\xF9-\xFC][_\W]{0,3}l[_\W]{0,3}t[_\W]{0,3}r[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}m_{0,3}\b/i -#vicodin -body __DRUGS_PAIN4 /(?:\b|\s)[_\W]{0,3}(?:\\\/|V)[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}c[_\W]{0,3}[o0\xF2-\xF6][_\W]{0,3}d[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}ns?[_\W]{0,3}(?:\b|\s)/i -#tramadol -body __DRUGS_PAIN5 /\b_{0,3}t[_\W]?r[_\W]?[a4\xE0-\xE6@][_\W]?m[_\W]?[a4\xE0-\xE6@][_\W]?d[_\W]?[o0\xF2-\xF6][_\W]?[l!|1]_{0,3}\b/i -# ultracet, uncommon in spam. -body __DRUGS_PAIN6 /\b_{0,3}u[_\W]?l[_\W]?t[_\W]?r[_\W]?a[_\W]?c[_\W]?e[_\W]?t_{0,3}\b/i -#fioricet -body __DRUGS_PAIN7 /\b_{0,3}f[_\W]?[i1!|l\xEC-\xEF][_\W]?[o0\xF2-\xF6][_\W]?r[_\W]?[i1!|l\xEC-\xEF][_\W]?c[_\W]?[e3\xE8-\xEB][_\W]?[t7]_{0,3}\b/i -#celebrex -body __DRUGS_PAIN8 /\b_{0,3}c[_\W]?[e3\xE8-\xEB][_\W]?l[_\W]?[e3\xE8-\xEB][_\W]?b[_\W]?r[_\W]?[e3\xE8-\xEB][_\W]?x_{0,3}\b/i -#imitrex -body __DRUGS_PAIN9 /(?:\b|\s)_{0,3}[i1!|l\xEC-\xEF]m[i1!|l\xEC-\xEF]tr[e3\xE8-\xEB]x_{0,3}\b/i -#vioxx -body __DRUGS_PAIN10 /(?:\b|\s)[_\W]{0,3}(?:\\\/|V)[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}[o0\xF2-\xF6][_\W]{0,3}x[_\W]{0,3}xx?_{0,3}\b/i -#zebutal, uncommon in spam. -body __DRUGS_PAIN11 /\bzebutal\b/i -#esgic plus, uncommon in spam. -body __DRUGS_PAIN12 /\besgic plus\b/i -#Darvon - a prescription narcotic -body __DRUGS_PAIN13 /\bD[_\W]?[a4\xE0-\xE6@][_\W]?r[_\W]?v[_\W]?[o0\xF2-\xF6][_\W]?n\b/i -body __DRUGS_PAIN14 /N[o0\xF2-\xF6]rc[o0\xF2-\xF6]/i -meta __DRUGS_PAIN (__DRUGS_PAIN1 || __DRUGS_PAIN2 || __DRUGS_PAIN3 || __DRUGS_PAIN4 ||__DRUGS_PAIN5 ||__DRUGS_PAIN6 ||__DRUGS_PAIN7 ||__DRUGS_PAIN8 || __DRUGS_PAIN9 || __DRUGS_PAIN10|| __DRUGS_PAIN11 || __DRUGS_PAIN12 || __DRUGS_PAIN13 ||__DRUGS_PAIN14) -#sleep aids -#ativan and lorazepam already under anxiety -#Ambien, brand of zolpidem tartrate -body __DRUGS_SLEEP1 /(?:\b|\s)[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}m[_\W]{0,3}b[_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}[e3\xE8-\xEB][_\W]{0,3}n[_\W]{0,3}(?:\b|\s)/i -#sonata, brand of zaleplon -body __DRUGS_SLEEP2 /(?:\b|\s)[_\W]{0,3}S[_\W]{0,3}[o0\xF2-\xF6][_\W]{0,3}n[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}t[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}(?:\b|\s)/i -#Restoril, brand of temazepam, uncommon in spam -body __DRUGS_SLEEP3 /\b_{0,3}R[_\W]?[e3\xE8-\xEB][_\W]?s[_\W]?t[_\W]?[o0\xF2-\xF6][_\W]?r[_\W]?i[_\W]?l_{0,3}\b/i -#Halcion, brand of triazolam -body __DRUGS_SLEEP4 /\b_{0,3}H[_\W]?[a4\xE0-\xE6@][_\W]?l[_\W]?c[_\W]?i[_\W]?[o0\xF2-\xF6][_\W]?n_{0,3}\b/i - -meta __DRUGS_SLEEP (__DRUGS_SLEEP1 || __DRUGS_SLEEP2 || __DRUGS_SLEEP3 ||__DRUGS_SLEEP4) - -#muscle relaxants -#soma - removed due to Bug 7612 -#body __DRUGS_MUSCLE1 /(?:\b|\s)[_\W]{0,3}s[_\W]{0,3}[o0\xF2-\xF6][_\W]{0,3}m[_\W]{0,3}[a4\xE0-\xE3\xE5\xE6@][_\W]{0,3}(?:\b|\s)/i -#cyclobenzaprine -body __DRUGS_MUSCLE2 /\b_{0,3}cycl[o0\xF2-\xF6]b[e3\xE8-\xEB]nz[a4\xE0-\xE6@]pr[i1!|l\xEC-\xEF]n[e3\xE8-\xEB]_{0,3}(?:\b|\s)/i -#flexeril -body __DRUGS_MUSCLE3 /\b_{0,3}f[_\W]?l[_\W]?[e3\xE8-\xEB][_\W]?x[_\W]?[e3\xE8-\xEB][_\W]?r[_\W]?[i1!|l\xEC-\xEF]_{0,3}[_\W]?l_{0,3}\b/i -#zanaflex -body __DRUGS_MUSCLE4 /\b_{0,3}z[_\W]?a[_\W]?n[_\W]?a[_\W]?f[_\W]?l[_\W]?e[_\W]?x_{0,3}\b/i -#skelaxin -body __DRUGS_MUSCLE5 /\bskelaxin\b/i -meta DRUGS_MUSCLE (__DRUGS_MUSCLE2 || __DRUGS_MUSCLE3 || __DRUGS_MUSCLE4 ||__DRUGS_MUSCLE5 ) -describe DRUGS_MUSCLE Refers to a muscle relaxant -#anti-anxiety -#these two rules are used to differentiate between obfu and non-obfu spellings -body __DRUGS_ANXIETY_XAN /xan[ae]x/i -body __DRUGS_ANXIETY_VAL /valium/i -#xanax - note: second a sometimes done as e. -body __DRUGS_ANXIETY1 /(?:\b|\s)[_\W]{0,3}x?x[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}n[_\W]{0,3}[ea4\xE1\xE2\xE3@][_\W]{0,3}xx?_{0,3}\b/i -#alprazolam -body __DRUGS_ANXIETY2 /\bAlprazolam\b/i -#valium -body __DRUGS_ANXIETY3 /(?:\b|\s)[_\W]{0,3}(?:\\\/|V)[_\W]{0,3}[a4\xE0-\xE6@][_\W]{0,3}[l|][_\W]{0,3}[i1!|l\xEC-\xEF][_\W]{0,3}[u\xB5\xF9-\xFC][_\W]{0,3}m\b/i -#diazepam, generic of valium -body __DRUGS_ANXIETY4 /\b_{0,3}D[_\W]?[i1!|l\xEC-\xEF][_\W]?[a4\xE0-\xE6@][_\W]?z[_\W]?[ea3\xE9\xEA\xEB][_\W]?p[_\W]?[a4\xE0-\xE6@][_\W]?m_{0,3}\b/i -#ativan -body __DRUGS_ANXIETY5 /(?:\b|\s)[a4\xE0-\xE6@][_\W]?t[_\W]?[i1!|l\xEC-\xEF][_\W]?v[_\W]?[a4\xE0-\xE6@][_\W]?n_{0,3}\b/i -#lorazepam - generic of ativan, uncommon in spam -body __DRUGS_ANXIETY6 /\b_{0,3}l[_\W]?[o0\xF2-\xF6][_\W]?r[_\W]?[a4\xE0-\xE6@][_\W]?z[_\W]?[e3\xE8-\xEB][_\W]?p[_\W]?[a4\xE0-\xE6@][_\W]?m_{0,3}\b/i -#clonazepam, generic. -body __DRUGS_ANXIETY7 /\b_{0,3}c[_\W]?l[_\W]?[o0\xF2-\xF6][_\W]?n[_\W]?[a4\xE0-\xE6@][_\W]?z[_\W]?e[_\W]?p[_\W]?[a4\xE0-\xE6@][_\W]?m\b/i -#klonopin, brand of clonazepam, uncommon in spam -body __DRUGS_ANXIETY8 /\bklonopin\b/i -#rivotril, brand of clonazepam, uncommon in spam -body __DRUGS_ANXIETY9 /\brivotril\b/i -meta DRUGS_ANXIETY (__DRUGS_ANXIETY1 || __DRUGS_ANXIETY2 || __DRUGS_ANXIETY3 || __DRUGS_ANXIETY4 ||__DRUGS_ANXIETY5 ||__DRUGS_ANXIETY6 ||__DRUGS_ANXIETY7 ||__DRUGS_ANXIETY8 || __DRUGS_ANXIETY9 ) -describe DRUGS_ANXIETY Refers to an anxiety control drug -meta DRUGS_ANXIETY_OBFU ( (__DRUGS_ANXIETY1 &&! __DRUGS_ANXIETY_XAN) || (__DRUGS_ANXIETY3 && !__DRUGS_ANXIETY_VAL)) -describe DRUGS_ANXIETY_OBFU Obfuscated reference to an anxiety control drug - -body DRUGS_SMEAR1 /(?:Viagra|Valium|Xanax|Soma|Cialis){2}/i -describe DRUGS_SMEAR1 Two or more drugs crammed together into one word - -#search for "weird" combinations that are unlikely to -#be prescribed together for a single event, thus unlikely to be -#mentioned in the same email, except an online pharmacy ad. -meta DRUGS_ANXIETY_EREC (DRUGS_ERECTILE && DRUGS_ANXIETY) -describe DRUGS_ANXIETY_EREC Refers to both an erectile and an anxiety drug -meta DRUGS_SLEEP_EREC (DRUGS_ERECTILE && __DRUGS_SLEEP) -describe DRUGS_SLEEP_EREC Refers to both an erectile and a sleep aid drug - -# note: some 3 item combos are "normal" ie: a patient might legitimately -# be prescribed depression, anxiety and sleep aid drugs all at once. -# however, I know of no "normal" 4-item combinations. -meta DRUGS_MANYKINDS (DRUGS_ERECTILE + DRUGS_DIET + __DRUGS_PAIN + __DRUGS_SLEEP + DRUGS_MUSCLE + DRUGS_ANXIETY > 3) -describe DRUGS_MANYKINDS Refers to at least four kinds of drugs - -######################################################################## - diff --git a/resources/spamassassin/20_dynrdns.cf b/resources/spamassassin/20_dynrdns.cf deleted file mode 100644 index 76a552ca..00000000 --- a/resources/spamassassin/20_dynrdns.cf +++ /dev/null @@ -1,213 +0,0 @@ -# SpamAssassin rules file: dynamic-ish rDNS tests -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# We should write a new ruletype for these, to save typing. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -# --------------------------------------------------------------------------- - -# Note the '^[^\]]+ ' stanza: this ensures that we only match spamware -# connecting to a internal relay; if a mail came from a dynamic addr but -# was relayed through their smarthost, that's fine. - -# See bug #5856, all references of "trusted" were changed to "external" - -# All of the RDNS_DYNAMIC rules require that the last external relay -# did not use SMTP authentication. These rules should not be firing on -# friendlies! -header __LAST_UNTRUSTED_RELAY_NO_AUTH X-Spam-Relays-Untrusted =~ /^[^\]]+ auth= / -header __LAST_EXTERNAL_RELAY_NO_AUTH X-Spam-Relays-External =~ /^[^\]]+ auth= / - -# dhcp024-210-034-053.columbus.rr.com [24.210.34.53] -# c-66-176-16-108.se.client2.attbi.com [66.176.16.108] -# c-67-168-174-61.client.comcast.net [67.168.174.61] -# NNN-NNN-NNN-NNN.fibertel.com.ar -# NN.NN.NNN.NNN.ap.yournet.ne.jp -# NN.NNN.NN-NN.rev.gaoland.net -# vaise-1-82-67-44-166.fbx.proxad.net [82.67.44.166] -# lns-vlq-11-62-147-186-141.adsl.proxad.net [62.147.186.141] -# dsl-200-95-109-107.prod-infinitum.com.mx [200.95.109.107] -# port-212-202-77-203.reverse.qsc.de [212.202.77.203] -# pool-151-203-32-68.bos.east.verizon.net [151.203.32.68] -# c-67-164-133-216.client.comcast.net [67.164.133.216] -# 200-171-228-6.customer.telesp.net.br [200.171.228.6] -# modemcable090.28-201-24.mc.videotron.ca [24.201.28.90] -# 80-218-47-160.dclient.hispeed.ch [80.218.47.160] -# cdm-68-226-239-16.laft.cox-internet.com [68.226.239.16] -# d53-64-35-171.nap.wideopenwest.com [64.53.171.35] -# 74.67-201-80.adsl.skynet.be [80.201.67.74] -# 12-218-225-223.client.mchsi.com [12.218.225.223] -# pptp-81-30-186-139.ufanet.ru [81.30.186.139] -# (require an alpha first, as legit HELO'ing-as-IP-address is hit otherwise) -header __RDNS_DYNAMIC_IPADDR X-Spam-Relays-External =~ /^[^\]]+ rdns=(?![^\s\]]+[-.]static[-.])\S*\d+[^\d\s]\d+[^\d\s]\d+[^\d\s]\d+\S*\.\S+\.\S/i -describe __RDNS_DYNAMIC_IPADDR Relay HELO'd using suspicious hostname (IP addr 1) - -# dhcp024-210-034-053.columbus.rr.com [24.210.34.53] -# catv-506237d8.miskcatv.broadband.hu [80.98.55.216] -# node-c-8b22.a2000.nl -# cm89.omega139.maxonline.com.sg -# cm114.gamma208.maxonline.com.sg -header __RDNS_DYNAMIC_DHCP X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*(?:cm|catv|docsis|cable|dsl|dhcp|cpe|node)\S*\d+[^\d\s]+\d/i -describe __RDNS_DYNAMIC_DHCP Relay HELO'd using suspicious hostname (DHCP) - -# fia83-8.dsl.hccnet.nl [62.251.8.83] -# fia160-115-100.dsl.hccnet.nl [80.100.115.160] -header __RDNS_DYNAMIC_HCC X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*\d+[^\d\s]+\d+\S*\.(?:docsis|cable|dsl|adsl|dhcp|cpe)\./i -describe __RDNS_DYNAMIC_HCC Relay HELO'd using suspicious hostname (HCC) - -# h0002a5d76857.ne.client2.attbi.com [65.96.12.59] -header __RDNS_DYNAMIC_ATTBI X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+\d+\S+\.client2\.attbi\.com/i -describe __RDNS_DYNAMIC_ATTBI Relay HELO'd using suspicious hostname (ATTBI.com) - -# CPE0004e2372711-CM000a73666706.cpe.net.cable.rogers.com -# CPE00e0184f0eba-CM014490118324.cpe.net.cable.rogers.com [24.43.109.140] -header __RDNS_DYNAMIC_ROGERS X-Spam-Relays-External =~ /^[^\]]+ rdns=CPE\d+\S+\.rogers\.com/i -describe __RDNS_DYNAMIC_ROGERS Relay HELO'd using suspicious hostname (Rogers) - -# ca-morpark-cuda1-zone7-b-159.vnnyca.adelphia.net[67.23.129.159] -# tn-greenvillecuda1cable7a-36.atlaga.adelphia.net [68.171.113.36] -# ky-richmond2a-123.rhmdky.adelphia.net [68.71.36.123] -# ny-lackawannacadent4-chtwga3a-b-117.buf.adelphia.net [68.71.205.117] -# fl-edel-u2-c3c-233.pbc.adelphia.net [68.64.89.233] -header __RDNS_DYNAMIC_ADELPHIA X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z]{2}-\S+-\d{1,3}\.[a-z]{3,8}\.adelphia\.net/i -describe __RDNS_DYNAMIC_ADELPHIA Relay HELO'd using suspicious hostname (Adelphia) - -# pD9E4F89F.dip.t-dialin.net [217.228.248.159] -header __RDNS_DYNAMIC_DIALIN X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z][A-F0-9]+\.dip\./ -describe __RDNS_DYNAMIC_DIALIN Relay HELO'd using suspicious hostname (T-Dialin) - -# 0xd5aaf40b.dhcp.kabelnettet.dk -# 0x50a46949.virnxx11.adsl-dhcp.tele.dk -header __RDNS_DYNAMIC_HEXIP X-Spam-Relays-External =~ /^[^\]]+ rdns=0x[a-f0-9]{8}\./ -describe __RDNS_DYNAMIC_HEXIP Relay HELO'd using suspicious hostname (Hex IP) - -# 118.Red-80-35-201.pooles.rima-tde.net -header __RDNS_DYNAMIC_SPLIT_IP X-Spam-Relays-External =~ /^[^\]]+ rdns=\d+\.\S+\d+[^\d\s]\d+[^\d\s]\d+[^\d\s]/ -describe __RDNS_DYNAMIC_SPLIT_IP Relay HELO'd using suspicious hostname (Split IP) - -# YahooBB219173000034.bbtec.net [219.173.0.34] -header __RDNS_DYNAMIC_YAHOOBB X-Spam-Relays-External =~ /^[^\]]+ rdns=YahooBB/i -describe __RDNS_DYNAMIC_YAHOOBB Relay HELO'd using suspicious hostname (YahooBB) - -# ool-18be1aaf.dyn.optonline.net [24.190.26.175] -header __RDNS_DYNAMIC_OOL X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+\.dyn\.optonline\.net/ -describe __RDNS_DYNAMIC_OOL Relay HELO'd using suspicious hostname (OptOnline) - -# wiley-170-10231.roadrunner.nf.net [205.251.210.249] -header __RDNS_DYNAMIC_RR2 X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z]+-\d{1,3}-\d{1,5}\.roadrunner/i -describe __RDNS_DYNAMIC_RR2 Relay HELO'd using suspicious hostname (RR 2) - -# pcp04024417pcs.toresd01.pa.comcast.net [68.86.206.126] -# bgp542174bgs.ewndsr01.nj.comcast.net[68.38.144.91] -# Computer-udp135632uds.union01.nj.comcast.net [68.39.99.32] -header __RDNS_DYNAMIC_COMCAST X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z-]+\d+[a-z]{3}\.[a-z0-9]+\...\.comcast/i -describe __RDNS_DYNAMIC_COMCAST Relay HELO'd using suspicious hostname (Comcast) - -# h234n2fls32o895.telia.com [217.208.73.234] -# h53n2fls32o828.telia.com -# h116n2fls32o1111.telia.com -# h29n1fls306o1003.telia.com -header __RDNS_DYNAMIC_TELIA X-Spam-Relays-External =~ /^[^\]]+ rdns=h\d+n\d+fls\S+\.telia\.com/i -describe __RDNS_DYNAMIC_TELIA Relay HELO'd using suspicious hostname (Telia) - -# CM-vina5-168-207.cm.vtr.net [200.104.168.207] -# CM-anto1-98-153.cm.vtr.net [200.104.98.153] -header __RDNS_DYNAMIC_VTR X-Spam-Relays-External =~ /^[^\]]+ rdns=cm-[a-z]+\d+-\d+-\d+\.cm\.vtr/i -describe __RDNS_DYNAMIC_VTR Relay HELO'd using suspicious hostname (VTR) - -# ec9z5l.cm.chello.no -header __RDNS_DYNAMIC_CHELLO_NO X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+\.cm\.chello\.no/i -describe __RDNS_DYNAMIC_CHELLO_NO Relay HELO'd using suspicious hostname (Chello.no) - -# g225174.upc-g.chello.nl -# a151145.upc-a.chello.nl -# a96134.upc-a.chello.nl -header __RDNS_DYNAMIC_CHELLO_NL X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z]\d+\.upc-[a-z]\.chello\.nl/i -describe __RDNS_DYNAMIC_CHELLO_NL Relay HELO'd using suspicious hostname (Chello.nl) - -# MG001182.user.veloxzone.com.br -# ba199058073.user.veloxzone.com.br -header __RDNS_DYNAMIC_VELOX X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z]{2}\d+\.user\.veloxzone\./i -describe __RDNS_DYNAMIC_VELOX Relay HELO'd using suspicious hostname (Veloxzone) - -# public4-seve6-5-cust173.lond.broadband.ntl.com -# spr1-bolt5-5-0-cust9.manc.broadband.ntl.com -# spc1-lewi4-6-0-cust190.lond.broadband.ntl.com -header __RDNS_DYNAMIC_NTL X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+\d+-\d+-cust\d+\.[a-z]{4,6}\.broadband\.ntl\.com/i -describe __RDNS_DYNAMIC_NTL Relay HELO'd using suspicious hostname (NTL) - -# (I'm quite sure these may be a good spamsign in future) -# nwblwi-nrp3-l10-a671.nwblwi.tds.net -header __RDNS_DYNAMIC_TDS X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+-[a-z]\d+\.[a-z]{6}\.tds\.net/i -header __RDNS_DYNAMIC_VIRTUA X-Spam-Relays-External =~ /^[^\]]+ rdns=\d+\.cps\./i - -# sp1-c700-131.spacelan.ne.jp -header __RDNS_DYNAMIC_SPACELAN X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+-[a-z]\d+-\d+\./i - -# rDNS host-type indicators, as per -# https://tools.ietf.org/id/draft-msullivan-dnsop-generic-naming-schemes-00.txt -header __RDNS_INDICATOR_DYN X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+[\-\.]dyn(?:amic)?[\-\.]/i - -# surprisingly large ham hitrate -header __RDNS_INDICATOR_TYPE X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+[\-\.](?:dial|modem|isdn|dov|\S?dsl|cable|wireless)[\-\.]/i - -# this hits a little ham, not too much though -header __RDNS_INDICATOR_RES X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+[\-\.](?:res|resnet|client)[\-\.]/i - -# these are non-standard, but common in the field; 100% spam correlation! -# (I think that's a fluke) -header __RDNS_INDICATOR_TYPE2 X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+[\-\.](?:docsis|dhcp|cpe|catv)[\-\.]/i - -# dsl.dynamic8510023760.ttnet.net.tr -header __RDNS_DYNAMIC_TTNET X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+[\-\.]dyn(?:amic)?\d/i - -# c221106.ppp.asahi-net.or.jp -# i253064.ppp.asahi-net.or.jp -# u035201.ppp.asahi-net.or.jp -# w158034.ppp.asahi-net.or.jp -header __RDNS_DYNAMIC_ASAHI X-Spam-Relays-External =~ /^[^\]]+ rdns=[a-z][0-9]+\.ppp\.asahi-net\.or\.jp/i - -# exceptions (bug 5397): -# exceptions: 66-220-155-151.mail-mail.facebook.com -# exceptions: o167-89-97-77.outbound-mail.sendgrid.net (bug 7592) -header __RDNS_STATIC X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*(?:fix|static|fixip|dedicated|mail\-mail|outbound-mail|smtp)/i - -# bug 5586: -header __CGATE_RCVD Received =~ /by \S+ \(CommuniGate Pro/ -# bug 5926: -header __DOMINO_RCVD Received =~ /by \S+ \(Lotus Domino / - -header __RDNS_NONE X-Spam-Relays-External =~ /^[^\]]+ rdns= / - -########################################################################### - -meta RDNS_DYNAMIC (__LAST_EXTERNAL_RELAY_NO_AUTH && !__RDNS_STATIC && (__RDNS_DYNAMIC_IPADDR || __RDNS_DYNAMIC_DHCP || __RDNS_DYNAMIC_HCC || __RDNS_DYNAMIC_ATTBI || __RDNS_DYNAMIC_ROGERS || __RDNS_DYNAMIC_ADELPHIA || __RDNS_DYNAMIC_DIALIN || __RDNS_DYNAMIC_HEXIP || __RDNS_DYNAMIC_SPLIT_IP || __RDNS_DYNAMIC_YAHOOBB || __RDNS_DYNAMIC_OOL || __RDNS_DYNAMIC_RR2 || __RDNS_DYNAMIC_COMCAST || __RDNS_DYNAMIC_TELIA || __RDNS_DYNAMIC_VTR || __RDNS_DYNAMIC_CHELLO_NO || __RDNS_DYNAMIC_CHELLO_NL || __RDNS_DYNAMIC_VELOX || __RDNS_DYNAMIC_NTL || __RDNS_DYNAMIC_TDS || __RDNS_DYNAMIC_VIRTUA || __RDNS_DYNAMIC_SPACELAN || __RDNS_INDICATOR_DYN || __RDNS_INDICATOR_RES || __RDNS_INDICATOR_TYPE2 || __RDNS_DYNAMIC_TTNET || __RDNS_DYNAMIC_ASAHI)) -describe RDNS_DYNAMIC Delivered to internal network by host with dynamic-looking rDNS - -meta RDNS_NONE (__RDNS_NONE && !__CGATE_RCVD && !__DOMINO_RCVD) -describe RDNS_NONE Delivered to internal network by a host with no rDNS - - diff --git a/resources/spamassassin/20_fake_helo_tests.cf b/resources/spamassassin/20_fake_helo_tests.cf deleted file mode 100644 index cedd0d9e..00000000 --- a/resources/spamassassin/20_fake_helo_tests.cf +++ /dev/null @@ -1,160 +0,0 @@ -# SpamAssassin rules file: fake-HELO tests -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# We should write a new ruletype for these, to save typing. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -#--------------------------------------------------------------------------- -# Handle hosts that look like HELO_DYNAMIC hosts - -# cmr-208-124-139-194.cr.net.cable.rogers.com) [208.124.139.194] -# cmr-208-97-119-114.cr.net.cable.rogers.com) [208.97.119.114] -header __HELO_STATIC_ROGERS X-Spam-Relays-External =~ /^[^\]]+ helo=cmr-\d{1,3}-\d{1,3}-\d{1,3}-\d{1,3}\S+\.rogers\.com[^\]]+ auth= /i - -# o167-89-97-77.outbound-mail.sendgrid.net (bug 7592) -header __HELO_STATIC_SENDGRID X-Spam-Relays-External =~ /^[^\]]+ helo=o\d{1,3}-\d{1,3}-\d{1,3}-\d{1,3}\.outbound-mail\.sendgrid\.net\s[^\]]+ auth= /i - -# 50-203-126-142-static.hfc.comcastbusiness.net -header __HELO_STATIC_COMCAST X-Spam-Relays-External =~ /^[^\]]+ helo=\d{1,3}-\d{1,3}-\d{1,3}-\d{1,3}-static\.hfc\.comcastbusiness\.net\s[^\]]+ auth= /i - -describe HELO_STATIC_HOST Relay HELO'd using static hostname -meta HELO_STATIC_HOST (__HELO_STATIC_ROGERS || __HELO_STATIC_SENDGRID || __HELO_STATIC_COMCAST) - -# --------------------------------------------------------------------------- - -# Suresh says: these will never be used as HELOs from real mail.com relays. -# Just check the most recent handover; the connection to a internal host. -# This way a legit sender can send to their MSA using that HELO (quite a few -# MUAs will do that), but a spammer gets caught. (List of domains comes from -# the drop-down list on the Mail.com signup page.) -#header FAKE_HELO_MAIL_COM_DOM X-Spam-Relays-External =~ /^[^\]]+ helo=(?:\S+\.|)(?:(?:mail|email|iname|cheerful|consultant|europe|mindless|myself|post|techie|usa|writeme|2die4|artlover|bikerider|catlover|cliffhanger|cutey|doglover|gardener|hot-shot|inorbit|loveable|mad\.scientist|playful|poetic|popstar|saintly|seductive|soon|whoever|winning|witty|yours|africamail|arcticmail|asia|australiamail|europe|japan|samerica|usa|berlin|dublin|london|madrid|moscowmail|munich|nycmail|paris|rome|sanfranmail|singapore|tokyo|accountant|adexec|allergist|alumnidirector|archaeologist|chemist|clerk|columnist|comic|consultant|counsellor|deliveryman|diplomats|doctor|dr|engineer|execs|financier|geologist|graphic-designer|insurer|journalist|lawyer|legislator|lobbyist|minister|optician|pediatrician|presidency|priest|publicist|realtyagent|registerednurses|repairman|representative|rescueteam|scientist|sociologist|teacher|techietechnologist|umpire)\.com|(?:programmer|earthling|hairdresser)\.net|musician\.org) /i -#describe FAKE_HELO_MAIL_COM_DOM Relay HELO'd with suspicious hostname (mail.com) - - -# --------------------------------------------------------------------------- -# Interesting new feature; spamware HELO'ing, from a dialup IP addr, -# using that IP's rDNS entry. We can catch this easily. There aren't -# many legit mailservers calling themselves -# 'dhcp024-210-034-053.columbus.rr.com'. ;) -# -# Note the '^[^\]]+ ' stanza: this ensures that we only match spamware -# connecting to a internal relay; if a mail came from a dynamic addr but -# was relayed through their smarthost, that's fine. - -# See bug #5856, all references of trusted were changed to internal - -# dhcp024-210-034-053.columbus.rr.com [24.210.34.53] -# c-66-176-16-108.se.client2.attbi.com [66.176.16.108] -# c-67-168-174-61.client.comcast.net [67.168.174.61] -# NNN-NNN-NNN-NNN.fibertel.com.ar -# NN.NN.NNN.NNN.ap.yournet.ne.jp -# NN.NNN.NN-NN.rev.gaoland.net -# vaise-1-82-67-44-166.fbx.proxad.net [82.67.44.166] -# lns-vlq-11-62-147-186-141.adsl.proxad.net [62.147.186.141] -# dsl-200-95-109-107.prod-infinitum.com.mx [200.95.109.107] -# port-212-202-77-203.reverse.qsc.de [212.202.77.203] -# pool-151-203-32-68.bos.east.verizon.net [151.203.32.68] -# c-67-164-133-216.client.comcast.net [67.164.133.216] -# 200-171-228-6.customer.telesp.net.br [200.171.228.6] -# modemcable090.28-201-24.mc.videotron.ca [24.201.28.90] -# 80-218-47-160.dclient.hispeed.ch [80.218.47.160] -# cdm-68-226-239-16.laft.cox-internet.com [68.226.239.16] -# d53-64-35-171.nap.wideopenwest.com [64.53.171.35] -# 74.67-201-80.adsl.skynet.be [80.201.67.74] -# 12-218-225-223.client.mchsi.com [12.218.225.223] -# (require an alpha first, as legit HELO'ing-as-IP-address is hit otherwise) -header __HELO_DYNAMIC_IPADDR X-Spam-Relays-External =~ /^[^\]]+ helo=(?![^\s\]]+[-.]static[-.])[a-z]\S*\d+[^\d\s]\d+[^\d\s]\d+[^\d\s]\d+[^\d\s][^\.]*\.\S+\.\S+[^\]]+ auth= /i -meta HELO_DYNAMIC_IPADDR (__HELO_DYNAMIC_IPADDR && !HELO_STATIC_HOST) -describe HELO_DYNAMIC_IPADDR Relay HELO'd using suspicious hostname (IP addr 1) - -# dhcp024-210-034-053.columbus.rr.com [24.210.34.53] -# catv-506237d8.miskcatv.broadband.hu [80.98.55.216] -# node-c-8b22.a2000.nl -# cm89.omega139.maxonline.com.sg -# cm114.gamma208.maxonline.com.sg -header __HELO_DYNAMIC_DHCP X-Spam-Relays-External =~ /^[^\]]+ helo=\S*(?:(? -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - -body __freemail_safe_fwd /---\s?(?:(?:Forwarded|Original) message|Alkuper(?:\xe4|\xc3\xa4)inen viesti)/i -header __freemail_safe_rls X-Spam-Relays-External =~ /^[^\]]+ rdns=\S+\.(?:tfbnw\.net|ebay\.com|tieto\.com) / -meta __freemail_safe __freemail_safe_fwd || __ML2 || __ML4 || __HAS_X_MAILING_LIST || __HAS_X_MAILMAN_VERSION || __freemail_safe_rls - -header __freemail_replyto eval:check_freemail_replyto('replyto') -meta FREEMAIL_REPLYTO __freemail_replyto && !__freemail_safe -describe FREEMAIL_REPLYTO Reply-To/From or Reply-To/body contain different freemails -score FREEMAIL_REPLYTO 2 - -header __freemail_reply eval:check_freemail_replyto('reply') -meta FREEMAIL_REPLY __freemail_reply && !__freemail_replyto && !__freemail_safe -describe FREEMAIL_REPLY From and body contain different freemails -score FREEMAIL_REPLY 0.5 - -header FREEMAIL_FROM eval:check_freemail_from() -describe FREEMAIL_FROM Sender email is commonly abused enduser mail provider -score FREEMAIL_FROM 0.001 - -header FREEMAIL_ENVFROM_END_DIGIT eval:check_freemail_header('EnvelopeFrom', '\d@') -describe FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit -score FREEMAIL_ENVFROM_END_DIGIT 0.1 - -header FREEMAIL_REPLYTO_END_DIGIT eval:check_freemail_header('Reply-To', '\d@') -describe FREEMAIL_REPLYTO_END_DIGIT Reply-To freemail username ends in digit -score FREEMAIL_REPLYTO_END_DIGIT 0.1 - -#header FREEMAIL_SUBJECT eval:check_freemail_header('Subject') -#describe FREEMAIL_SUBJECT Subject contains freemail -#score FREEMAIL_SUBJECT 0.001 - -# Idea from John Hardin -header __freemail_hdr_replyto eval:check_freemail_header('Reply-To') -meta FREEMAIL_FORGED_REPLYTO __freemail_hdr_replyto && !FREEMAIL_FROM && !__freemail_safe -describe FREEMAIL_FORGED_REPLYTO Freemail in Reply-To, but not From -score FREEMAIL_FORGED_REPLYTO 0.1 - -endif - diff --git a/resources/spamassassin/20_freemail_domains.cf b/resources/spamassassin/20_freemail_domains.cf deleted file mode 100644 index 52cd505f..00000000 --- a/resources/spamassassin/20_freemail_domains.cf +++ /dev/null @@ -1,545 +0,0 @@ -# SpamAssassin - FreeMail domains file -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -# List contains commonly abused end user mail providers -# "freemail" is solely used for label purposes. - -# weed out domains that already exist given a FILE of one domain per line: -# perl -lane 'if (@F and shift(@F) eq "freemail_domains") { -# for (@F) { s/\./\\./g; s/\?/./g; s/\*/[^.]*/g; print } -# }' rules/*.cf |grep -wvf- FILE - -# Updated 2016-08-18-axb - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - -# Initial import from old FreeMail.pm / 090428 -freemail_domains 020.co.uk 123.com 123box.net 123india.com 123mail.cl -freemail_domains 123mail.org 123qwe.co.uk 138mail.com 141.ro 150mail.com 150ml.com 16mail.com -freemail_domains 1963chevrolet.com 1963pontiac.com 1netdrive.com 1st-website.com 1stpd.net -freemail_domains 2-mail.com 20after4.com 21cn.com 24h.co.jp 24horas.com 271soundview.com -freemail_domains 2die4.com 2mydns.com 2net.us 3000.it 3ammagazine.com 3email.com 3xl.net -freemail_domains 444.net 4email.com 4email.net 4newyork.com 50mail.com 55mail.cc 5fm.za.com -freemail_domains 6210.hu 6sens.com 702mail.co.za 7110.hu 8848.net 8m.com 8m.net 8x.com.br 8u8.com 8u8.hk 8u8.tw -freemail_domains a-topmail.at about.com abv.bg acceso.or.cr access4less.net accessgcc.com -freemail_domains acmemail.net adiga.com adinet.com.uy -freemail_domains adres.nl advalvas.be aeiou.pt aeneasmail.com afrik.com -freemail_domains afropoets.com aggies.com ahaa.dk aichi.com aim.com airpost.net aiutamici.com -freemail_domains aklan.com aknet.kg alabama.usa.com alaska.usa.com alavatotal.com -freemail_domains albafind.com albawaba.com alburaq.net aldeax.com aldeax.com.ar alex4all.com aliyun.com -freemail_domains alexandria.cc algeria.com alice.it allmail.net -freemail_domains alskens.dk altavista.se altbox.org alternativagratis.com alum.com -freemail_domains alunos.unipar.br alvilag.hu amenworld.com america.hm -freemail_domains americamail.com amnetsal.com amorous.com ananzi.co.za anet.ne.jp anfmail.com -freemail_domains angelfire.com animail.net aniverse.com anjungcafe.com -freemail_domains another.com antedoonsub.com antwerpen.com anunciador.net anytimenow.com -freemail_domains aol.* aol.co*.* aon.at apexmail.com apollo.lv approvers.net aprava.com -freemail_domains apropo.ro arcor.de argentina.com -freemail_domains arizona.usa.com arkansas.usa.com armmail.com army.com arnet.com.ar aroma.com -freemail_domains arrl.net aruba.it asheville.com asia-links.com -freemail_domains asiamail.com assala.com assamesemail.com asurfer.com -freemail_domains atl.lv atlas.cz atlas.sk atozasia.com atreillou.com att.net *.att.ne.jp au.ru aubenin.com -freemail_domains aus-city.com aussiemail.com.au avasmail.com.mv axarnet.com -freemail_domains ayna.com azet.sk babbalu.com badgers.com bakpaka.com bakpaka.net -freemail_domains balochistan.org baluch.com bama-fan.com bancora.net bankersmail.com -freemail_domains barlick.net beeebank.com beehive.org -freemail_domains been-there.com beirut.com belizehome.com belizemail.net -freemail_domains belizeweb.com bellsouth.net berlin.de bestmail.us bflomail.com -freemail_domains bgnmail.com bharatmail.com big-orange.com bigboss.cz bigfoot.com bigger.com -freemail_domains bigmailbox.com bigmir.net bigstring.com bip.net bigpond.com -freemail_domains bitwiser.com biz.by bizhosting.com black-sea.ro blackburnmail.com -freemail_domains blackglobalnetwork.net blink182.net blue.devils.com bluebottle.com -freemail_domains bluemail.ch blumail.org blvds.com bol.com.br bolando.com -freemail_domains bollywood2000.com bollywoodz.com bombka.dyn.pl bonbon.net boom.com -freemail_domains bootmail.com bostonoffice.com box.az boxbg.com boxemail.com brain.com.pk -freemail_domains brasilia.net bravanese.com brazilmail.com.br breathe.com -freemail_domains brestonline.com brfree.com.br brujula.net btcc.org -freemail_domains buffaloes.com bulgaria.com bulldogs.com bumerang.ro burntmail.com -freemail_domains butch-femme.net buzy.com buzzjakkerz.com c-box.cz c3.hu c4.com cadinfo.net -freemail_domains calcfacil.com.br calcware.org california.usa.com -freemail_domains callnetuk.com camaroclubsweden.com canada-11.com canada.com canal21.com -freemail_domains canoemail.com caramail.com cardblvd.com care-mail.com care2.com caress.com -freemail_domains carioca.net cashette.com casino.com casinomail.com cataloniamail.com -freemail_domains catalunyamail.com cataz.com catcha.com catholic.org caths.co.uk -freemail_domains caxess.net cbrmail.com cc.lv cemelli.com centoper.it centralpets.com -freemail_domains centrum.cz centrum.sk centurylink.net cercaziende.it cgac.es chaiyo.com chaiyomail.com -freemail_domains chance2mail.com channelonetv.com charter.net chattown.com checkitmail.at -freemail_domains chelny.com cheshiremail.com chil-e.com chillimail.com -freemail_domains china.com christianmail.org ciaoweb.it cine.com ciphercom.net -freemail_domains circlemail.com cititrustbank1.cjb.net citromail.hu citynetusa.com ciudad.com.ar -freemail_domains claramail.com classicmail.co.za cliffhanger.com clix.pt -freemail_domains close2you.net cluemail.com clujnapoca.ro collegeclub.com -freemail_domains colombia.com colorado.usa.com comcast.net comfortable.com -freemail_domains compaqnet.fr compuserve.com computer.net computermail.net -freemail_domains computhouse.com conevyt.org.mx connect4free.net connecticut.usa.com -freemail_domains coolgoose.com coolkiwi.com coollist.com coxinet.net -freemail_domains coolmail.com coolmail.net coolsend.com cooltoad.com cooperation.net -freemail_domains copacabana.com copticmail.com corporateattorneys.com corporation.net -freemail_domains correios.net.br correomagico.com cosmo.com cosmosurf.net cougars.com -freemail_domains count.com countrybass.com couple.com criticalpath.net -freemail_domains critterpost.com crosspaths.net crosswinds.net cryingmail.com cs.com -freemail_domains csucsposta.hu cumbriamail.com curio-city.com custmail.com -freemail_domains cwazy.co.uk cwazy.net cww.de cyberaccess.com.pk -freemail_domains cybergirls.dk cyberguys.dk cybernet.it cymail.net -freemail_domains dabsol.net dada.net dadanet.it dailypioneer.com damuc.org.br -freemail_domains dansegulvet.com darkhorsefan.net data54.com davegracey.com dayzers.com -freemail_domains daum.net dbmail.com dcemail.com dcsi.net deacons.com deadlymob.org deal-maker.com -freemail_domains dearriba.com degoo.com delajaonline.org delaware.usa.com delfi.lv -freemail_domains delhimail.com demon.deacons.com desertonline.com -freemail_domains desidrivers.com deskpilot.com despammed.com detik.com devils.com dexara.net -freemail_domains dhmail.net di-ve.com didamail.com digitaltrue.com -freemail_domains direccion.com director-general.com diri.com discardmail.com -freemail_domains discoverymail.net disinfo.net djmillenium.com dmailman.com -freemail_domains dnsmadeeasy.com do.net.ar dodgeit.com dogmail.co.uk -freemail_domains doityourself.com domaindiscover.com domainmanager.com doneasy.com -freemail_domains dontexist.org dores.com dostmail.com dot5hosting.com dotcom.fr -freemail_domains dotnow.com dott.it doubt.com dplanet.ch dragoncon.net dragonfans.com -freemail_domains dropzone.com dserver.org dubaiwebcity.com dublin.ie dustdevil.com -freemail_domains dynamitemail.com dyndns.org e-apollo.lv e-hkma.com -freemail_domains e-mail.cz e-mail.ph e-mailanywhere.com e-milio.com e-tapaal.com e-webtec.com earthalliance.com -freemail_domains earthling.net eastmail.com eastrolog.com easy-pages.com easy.com -freemail_domains easyinfomail.co.za easypeasy.com echina.com ecn.org ecplaza.net eircom.net -freemail_domains edsamail.com.ph educacao.te.pt edumail.co.za eeism.com ego.co.th ekolay.net -freemail_domains elforotv.com.ar elitemail.org elsitio.com eltimon.com elvis.com -freemail_domains email.com.br email.cz email.bg email.it email.lu email.lviv.ua email.nu -freemail_domains email.ro email.si email2me.com emailacc.com emailaccount.com -freemail_domains emailaddresses.com emailchoice.com emailcorner.net emailn.de emailengine.net -freemail_domains emailengine.org emailgaul.com emailgroups.net emailhut.net emailpinoy.com -freemail_domains emailplanet.com emailplus.org emailuser.net ematic.com embarqmail.com -freemail_domains embroideryforums.com eml.cc emoka.ro emptymail.com enel.net enelpunto.net -freemail_domains england.com enterate.com.ar entryweb.it entusiastisk.com -freemail_domains enusmail.com epatra.com epix.net epomail.com epost.de eprompter.com eqqu.com -freemail_domains eramail.co.za eresmas.com eriga.lv ertelecom.ru esde-s.org esfera.cl estadao.com.br -freemail_domains etllao.com euromail.net euroseek.com -freemail_domains euskalmail.com evafan.com everyday.com.kh everymail.net everyone.net -freemail_domains excite.* excite.co*.* execs2k.com executivemail.co.za -freemail_domains expn.com ezilon.com ezrs.com f-m.fm facilmail.com fadrasha.net fadrasha.org -freemail_domains faithhighway.com faithmail.com familymailbox.com familyroll.com -freemail_domains familysafeweb.net fan.com fan.net faroweb.com fast-email.com fast-mail.org -freemail_domains fastem.com fastemail.us fastemailer.com fastermail.com fastest.cc -freemail_domains fastimap.com fastmail.* fastmail.co*.* fastmailbox.net -freemail_domains fastmessaging.com fastwebmail.it fawz.net fea.st federalcontractors.com -freemail_domains fedxmail.com feelings.com female.ru fepg.net ffanet.com fiberia.com -freemail_domains filipinolinks.com financesource.com findmail.com -freemail_domains fiscal.net flashmail.com flipcode.com florida.usa.com floridagators.com -freemail_domains fmail.co.uk fmailbox.com fmgirl.com fmguy.com fnmail.com footballer.com foxmail.com -freemail_domains forfree.at forsythmissouri.org fortuncity.com forum.dk free.com.pe free.fr -freemail_domains free.net.nz freeaccess.nl freegates.be freeghana.com freehosting.nl -freemail_domains freei.co.th freeler.nl freemail.* freemail.*.* freemail.globalsite.com.br -freemail_domains freemuslim.net freenet.de freenet.kg freeola.net freepgs.com freesbee.fr -freemail_domains freeservers.com freestart.hu freesurf.ch freesurf.fr -freemail_domains freesurf.nl freeuk.com freeuk.net freeweb.it freewebemail.com freeyellow.com -freemail_domains frisurf.no frontiernet.net fsmail.net fsnet.co.uk ftml.net fuelie.org -freemail_domains fun-greetings-jokes.com fun.21cn.com fusemail.com fut.es gala.net -freemail_domains galmail.co.za gamebox.net gamecocks.com gawab.com gay.com -freemail_domains gaymailbox.com gaza.net gazeta.pl gci.net gdi.net geeklife.com gemari.or.id -freemail_domains genxemail.com geopia.com georgia.usa.com getmail.no -freemail_domains ggaweb.ch giga4u.de gjk.dk glay.org glendale.net globalfree.it globomail.com -freemail_domains globalpinoy.com globalsite.com.br globalum.com globetrotter.net gmail.com -freemail_domains gmx.* go-bama.com go-cavs.com go-chargers.com go-dawgs.com go-gators.com -freemail_domains go-hogs.com go-irish.com go-spartans.com go-tigers.com go.aggies.com -freemail_domains go.air-force.com go.badgers.com go.big-orange.com go.blue.devils.com -freemail_domains go.buffaloes.com go.bulldogs.com go.com go.cougars.com go.dores.com -freemail_domains go.gamecocks.com go.huskies.com go.longhorns.com go.mustangs.com -freemail_domains go.rebels.com go.ro go.ru go.terrapins.com go.wildcats.com go.wolverines.com -freemail_domains go.yellow-jackets.com go2net.com go4.it gofree.co.uk golfemail.com -freemail_domains goliadtexas.com gomail.com.ua gonowmail.com gonuts4free.com googlemail.com -freemail_domains goplay.com gorontalo.net gotmail.com gotomy.com govzone.com grad.com -freemail_domains graffiti.net gratisweb.com gtechnics.com -freemail_domains guate.net guessmail.com gwalla.com h-mail.us haberx.com hailmail.net -freemail_domains halejob.com hamptonroads.com handbag.com hanmail.net happemail.com -freemail_domains happycounsel.com hawaii.com hawaii.usa.com hayahaya.tg hedgeai.com -freemail_domains heesun.net heremail.com hetnet.nl highveldmail.co.za hildebrands.de -freemail_domains hingis.org hispavista.com hitmanrecords.com hockeyghiaccio.com -freemail_domains hockeymail.com holapuravida.com home.no.net home.ro home.se homelocator.com -freemail_domains homemail.co.za homenetmail.com homestead.com homosexual.net hongkong.com hong-kong-1.com -freemail_domains hopthu.com hosanna.net hot.ee hotbot.com hotbox.ru hotcoolmail.com hotdak.com -freemail_domains hotfire.net hotinbox.com hotmail.* hotmail.co*.* -freemail_domains hotpop.com hotvoice.com hour.com howling.com huhmail.com -freemail_domains humour.com hurra.de hush.ai hush.com hushmail.com huskies.com -freemail_domains hutchcity.com i-france.com i-p.com i12.com i2828.com ibatam.com ibest.com.br -freemail_domains ibizdns.com icafe.com ice.is icestorm.com icloud.com icq.com icqmail.com icrazy.com -freemail_domains id.ru idaho.usa.com idirect.com idncafe.com ieg.com.br iespalomeras.net -freemail_domains iespana.es ifrance.com ig.com.br ignazio.it illinois.usa.com ilse.net -freemail_domains ilse.nl imail.ru imailbox.com imap-mail.com imap.cc imapmail.org imel.org -freemail_domains in-box.net inbox.com inbox.ge inbox.lv inbox.net inbox.ru in.com -freemail_domains incamail.com indexa.fr india.com indiamail.com indiana.usa.com -freemail_domains indiatimes.com induquimica.org inet.com.ua infinito.it infoapex.com -freemail_domains infohq.com infomail.es infomart.or.jp infosat.net infovia.com.ar inicia.es -freemail_domains inmail.sk inmail24.com inoutbox.com -freemail_domains intelnet.net.gt intelnett.com interblod.com -freemail_domains interfree.it interia.pl interlap.com.ar intermail.hu internet-e-mail.com -freemail_domains internet-mail.org internet.lu internetegypt.com internetemails.net -freemail_domains internetmailing.net inwind.it iobox.com iobox.fi iol.it iol.pt iowa.usa.com -freemail_domains ip3.com ipermitmail.com iqemail.com iquebec.com iran.com irangate.net -freemail_domains iscool.net islandmama.com ismart.net isonews2.com isonfire.com isp9.net -freemail_domains ispey.com itelgua.com itloox.com itmom.com -freemail_domains ivenus.com iwan-fals.com iwon.com ixp.net japan.com jaydemail.com -freemail_domains jedrzejow.pl jetemail.net jingjo.net jippii.fi jmail.co.za jojomail.com -freemail_domains jovem.te.pt joymail.com jubii.dk jubiipost.dk jumpy.it -freemail_domains juno.com justemail.net justmailz.com k.ro kaazoo.com kabissa.org kaixo.com -freemail_domains kalluritimes.com kalpoint.com kansas.usa.com katamail.com kataweb.it -freemail_domains kayafmmail.co.za keko.com.ar kentucky.usa.com keptprivate.com -freemail_domains kimo.com kiwitown.com klik.it klikni.cz kmtn.ru koko.com kolozsvar.ro kombud.com -freemail_domains koreanmail.com kotaksuratku.info krunis.com kukamail.com -freemail_domains kuronowish.com kyokodate.com kyokofukada.net ladymail.cz lagoon.nc -freemail_domains lahaonline.com lamalla.net lancsmail.com land.ru laposte.net latinmail.com -freemail_domains lawyer.com lawyersmail.com lawyerzone.com lebanonatlas.com leehom.net -freemail_domains leonardo.it leonlai.net letsjam.com letterbox.org -freemail_domains letterboxes.org levele.com lexpress.net libero.it liberomail.com -freemail_domains libertysurf.net libre.net lightwines.org linkmaster.com linuxfreemail.com -freemail_domains lionsfan.com.au live.* livedoor.com llandudno.com -freemail_domains llangollen.com lmxmail.sk loggain.net loggain.nu lolnetwork.net -freemail_domains london.com longhorns.com look.com looksmart.co.uk looksmart.com -freemail_domains looksmart.com.au loteria.net lotonazo.com louisiana.usa.com louiskoo.com -freemail_domains loveable.com lovemail.com lovingjesus.com lpemail.com luckymail.com luso.pt -freemail_domains lusoweb.pt luukku.com lycos.* lycos.co*.* lycosmail.com mac.com -freemail_domains machinecandy.com macmail.com mad.scientist.com madcrazy.com -freemail_domains madonno.com madrid.com mag2.com magicmail.co.za magik-net.com mail-atlas.net -freemail_domains mail-awu.de mail-box.cz mail.by mail-center.com mail-central.com mail-jp.org -freemail_domains mail-online.dk mail-page.com mail-x-change.com mail.austria.com mail.az -freemail_domains mail.de mail.be mail.bg mail.bulgaria.com mail.co.za mail.dk mail.ee -freemail_domains mail.goo.ne.jp mail.gr mail.lawguru.com mail.md mail.mn mail.org mail.pf -freemail_domains mail.pt mail.ru mail.yahoo.co.jp mail15.com mail2*.com mail3000.com mail333.com -freemail_domains mail8.com mailandftp.com mailandnews.com mailas.com mailasia.com mailbg.com -freemail_domains mailblocks.com mailbolt.com mailbox.as mailbox.co.za mailbox.gr mailbox.hu -freemail_domains mailbox.sk mailc.net mailcan.com mailcircuit.com mailclub.fr mailclub.net -freemail_domains maildozy.com mailfly.com mailforce.net mailftp.com mailglobal.net -freemail_domains mailhaven.com mailinator.com mailingaddress.org mailingweb.com mailisent.com -freemail_domains mailite.com mailme.dk mailmight.com mailmij.nl mailnew.com mailops.com -freemail_domains mailpanda.com mailpersonal.com mailroom.com mailru.com mails.de mailsent.net -freemail_domains mailserver.dk mailservice.ms mailsnare.net mailsurf.com mailup.net -freemail_domains mailvault.com mailworks.org maine.usa.com majorana.martina-franca.ta.it -freemail_domains maktoob.com malayalamtelevision.net malayalapathram.com male.ru manager.de -freemail_domains manlymail.net mantrafreenet.com mantramail.com mantraonline.com -freemail_domains marihuana.ro marijuana.nl marketweighton.com maryland.usa.com -freemail_domains masrawy.com massachusetts.usa.com mauimail.com mbox.com.au mcrmail.com me.by me.com -freemail_domains medicinatv.com meetingmall.com megamail.pt menara.ma merseymail.com mesra.net -freemail_domains messagez.com metacrawler.com mexico.com miaoweb.net -freemail_domains michigan.usa.com micro2media.com miesto.sk mighty.co.za milacamn.net -freemail_domains milmail.com mindless.com mindviz.com minnesota.usa.com -freemail_domains mississippi.usa.com missouri.usa.com mixmail.com ml1.net ml2clan.com -freemail_domains mlanime.com mm.st mmail.com mobimail.mn mobsters.com mobstop.com -freemail_domains modemnet.net modomail.com moldova.com moldovacc.com monarchy.com -freemail_domains montana.usa.com montevideo.com.uy moomia.com moose-mail.com mosaicfx.com -freemail_domains motormania.com movemail.com mr.outblaze.com mrspender.com -freemail_domains ms*.hinet.net mscold.com msn.com msn.co.uk msnzone.cn mundo-r.com -freemail_domains muslimsonline.com mustangs.com mxs.de myblue.cc mycabin.com mycity.com mycommail.com -freemail_domains mycool.com mydomain.com myeweb.com myfastmail.com myfunnymail.com mygrande.net mykolab.com -freemail_domains mygamingconsoles.com myiris.com myjazzmail.com mymacmail.com mymail.dk -freemail_domains mymail.ph.inter.net mymail.ro mynet.com mynet.com.tr myotw.net myopera.com -freemail_domains myownemail.com mypersonalemail.com myplace.com myrealbox.com -freemail_domains myspace.com myt.mu myway.com mzgchaos.de n2.com n2business.com n2mail.com -freemail_domains n2software.com nabble.com name.com nameplanet.com nanamail.co.il -freemail_domains nanaseaikawa.com nandomail.com naseej.com nastything.com national-champs.com -freemail_domains nativeweb.net narod.ru nate.com naveganas.com naver.com nebraska.usa.com nemra1.com nenter.com -freemail_domains nerdshack.com nervhq.org net.hr net4b.pt net4jesus.com net4you.at -freemail_domains netbounce.com netcabo.pt netcape.net netcourrier.com netexecutive.com -freemail_domains netfirms.com netkushi.com netmongol.com netpiper.com netposta.net -freemail_domains netscape.com netscape.net netscapeonline.co.uk netsquare.com nettaxi.com -freemail_domains netti.fi networld.com netzero.com netzero.net neustreet.com nevada.usa.com -freemail_domains newhampshire.usa.com newjersey.usa.com newmail.com newmail.net -freemail_domains newmail.ok.com newmail.ru newmexico.usa.com newspaperemail.com newyork.com -freemail_domains newyork.usa.com newyorkcity.com nfmail.com nicegal.com nightimeuk.com -freemail_domains nightly.com nightmail.com nightmail.ru noavar.com noemail.com nonomail.com nokiamail.com -freemail_domains noolhar.com northcarolina.usa.com northdakota.usa.com -freemail_domains nospammail.net nowzer.com ny.com nyc.com nz11.com -freemail_domains nzoomail.com o2.pl oceanfree.net ocsnet.net oddpost.com odeon.pl -freemail_domains odmail.com offshorewebmail.com ofir.dk ohio.usa.com oicexchange.com ok.ru -freemail_domains oklahoma.usa.com ole.com oleco.net olympist.net omaninfo.com onatoo.com -freemail_domains ondikoi.com onebox.com onenet.com.ar onet.pl ongc.net oninet.pt online.ie -freemail_domains online.ru onlinewiz.com onobox.com open.by openbg.com openforyou.com -freemail_domains opentransfer.com operamail.com oplusnet.com orange.fr orangehome.co.uk orange.es orange.jo orange.pl -freemail_domains orbitel.bg orcon.net.nz oregon.usa.com oreka.com organizer.net orgio.net -freemail_domains orthodox.com osite.com.br oso.com ourbrisbane.com ournet.md -freemail_domains ourprofile.net ourwest.com outgun.com outlook.* ownmail.net oxfoot.com ozu.es -freemail_domains pacer.com paginasamarillas.com -freemail_domains pakistanmail.com pandawa.com pando.com pandora.be paris.com parsimail.com -freemail_domains parspage.com patmail.com pattayacitythailand.com pc4me.us pcpostal.com -freemail_domains penguinmaster.com pennsylvania.usa.com peoplepc.com peopleweb.com -freemail_domains personal.ro personales.com peru.com petml.com -freemail_domains phreaker.net pigeonportal.com pilu.com pimagop.com -freemail_domains pinoymail.com pipni.cz pisem.net planet-school.de planetaccess.com -freemail_domains planetout.com plasa.com playersodds.com playful.com pluno.com -freemail_domains plusmail.com.br pmail.net pnetmail.co.za pobox.ru pobox.sk pochtamt.ru pochta.ru -freemail_domains poczta.fm poetic.com pogowave.com polbox.com -freemail_domains pop3.ru pop.co.th popmail.com poppymail.com popsmail.com popstar.com portafree.com -freemail_domains portaldosalunos.com portugalmail.com portugalmail.pt post.cz -freemail_domains post.expart.ne.jp post.pl post.sk posta.ge postaccesslite.com postiloota.net -freemail_domains postinbox.com postino.ch postino.it postmaster.co.uk postpro.net praize.com -freemail_domains press.co.jp primposta.com printesamargareta.ro -freemail_domains private.21cn.com probemail.com profesional.com profession.freemail.com.br -freemail_domains proinbox.com promessage.com prontomail.com protonmail.com protonmail.ch -freemail_domains provincial.net publicaccounting.com punkass.com puppy.com.my -freemail_domains q.com qatar.io qlmail.com qq.com qrio.com qsl.net qudsmail.com queerplaces.com quepasa.com -freemail_domains quick.cz quickwebmail.com r-o-o-t.com r320.hu raakim.com rbcmail.ru racingseat.com -freemail_domains radicalz.com radiojobbank.com ragingbull.com -freemail_domains raisingadaughter.com rallye-webmail.com rambler.ru ranmamail.com ravearena.com -freemail_domains ravemail.co.za razormail.com real.ro realemail.net reallyfast.biz -freemail_domains reallyfast.info rebels.com recife.net recme.net -freemail_domains rediffmail.com rediffmailpro.com redseven.de redwhitearmy.com -freemail_domains relia.com -freemail_domains revenue.com rexian.com rhodeisland.usa.com -freemail_domains ritmes.net rn.com roanokemail.com rochester-mail.com rock.com rocketmail.com -freemail_domains rockfan.com rockinghamgateway.com rojname.com rol.ro -freemail_domains rollin.com rome.com romymichele.com royal.net rpharmacist.com rt.nl ru.ru -freemail_domains rushpost.com russiamail.com rxpost.net s-mail.com saabnet.com -freemail_domains sacbeemail.com sacmail.com safe-mail.net safe-mailbox.com -freemail_domains saigonnet.vn saint-mike.org -freemail_domains samilan.net sandiego.com sanook.com sanriotown.com -freemail_domains sapibon.com sapo.pt saturnfans.com sayhi.net sbcglobal.com scfn.net -freemail_domains schweiz.org sci.fi sciaga.pl -freemail_domains scrapbookscrapbook.com seapole.com search417.com seark.com sebil.com -freemail_domains secretservices.net secure-jlnet.com seductive.com sendmail.ru -freemail_domains sendme.cz sent.as sent.at sent.com serga.com.ar sermix.com server4free.de -freemail_domains serverwench.com sesmail.com sexmagnet.com seznam.cz shadango.com she.com -freemail_domains shuf.com siamlocalhost.com siamnow.net sify.com sinamail.com singapore.com -freemail_domains singmail.com singnet.com.sg siraj.org sirindia.com sirunet.com sister.com sina.com sina.cn sinanail.com -freemail_domains sistersbrothers.com sizzling.com slamdunkfan.com slickriffs.co.uk -freemail_domains slingshot.com slo.net slomusic.net smartemail.co.uk smtp.ru snail-mail.net -freemail_domains sndt.net sneakemail.com snoopymail.com snowboarding.com -freemail_domains so-simple.org socamail.com softhome.net sohu.com -freemail_domains sol.dk solidmail.com soon.com sos.lv soundvillage.org -freemail_domains southcarolina.usa.com southdakota.usa.com space.com spacetowns.com -freemail_domains spamex.com spartapiet.com speed-racer.com speedpost.net -freemail_domains speedymail.org spils.com spinfinder.com sportemail.com spray.net spray.no -freemail_domains spray.se spymac.com srbbs.com srilankan.net ssan.com ssl-mail.com stade.fr -freemail_domains stalag13.com stampmail.com starbuzz.com starline.ee starmail.com -freemail_domains starmail.org starmedia.com starspath.com start.com.au start.no stribmail.com -freemail_domains strompost.* student.com student.ednet.ns.ca studmail.com sudanmail.net -freemail_domains suisse.org sunbella.net sunmail1.com sunpoint.net sunrise.ch -freemail_domains sunumail.sn sunuweb.net suomi24.fi superdada.it supereva.com supereva.it -freemail_domains supermailbox.com superposta.com surf3.net surfassistant.com surfsupnet.net -freemail_domains surfy.net surimail.com surnet.cl sverige.nu svizzera.org -freemail_domains sweb.cz swift-mail.com swissinfo.org -freemail_domains swissmail.net switzerland.org syom.com syriamail.com t-mail.com t-net.net.ve -freemail_domains t2mail.com tabasheer.com talk21.com talkcity.com tangmonkey.com tatanova.com -freemail_domains taxcutadvice.com techemail.com technisamail.co.za -freemail_domains teenmail.co.uk teenmail.co.za tejary.com telebot.com telefonica.net -freemail_domains telegraf.by teleline.es telinco.net telkom.net telpage.net telstra.com telenet.be -freemail_domains telusplanet.net tempting.com tenchiclub.com tennessee.usa.com -freemail_domains terrapins.com texas.usa.com texascrossroads.com tfz.net thai.com -freemail_domains thaimail.com thaimail.net the-fastest.net the-quickest.com thegame.com -freemail_domains theinternetemail.com theoffice.net thepostmaster.net -freemail_domains theracetrack.com theserverbiz.com thewatercooler.com -freemail_domains thewebpros.co.uk thinkpost.net thirdage.com thundermail.com tim.it -freemail_domains timemail.com tin.it tinati.net tiscali.* tiscali.co*.* tiscalinet.it -freemail_domains tjohoo.se tkcity.com tlcfan.com tlen.pl tmicha.net todito.com todoperros.com -freemail_domains tokyo.com topchat.com topmail.com.ar topmail.dk topmail.co.ie topmail.co.in topmail.co.nz topmail.co.uk topmail.co.za -freemail_domains topsurf.com toquedequeda.com torba.com torchmail.com -freemail_domains totalmail.com totalsurf.com totonline.net tough.com toughguy.net trav.se -freemail_domains trevas.net tripod-mail.com triton.net trmailbox.com tsamail.co.za -freemail_domains turbonett.com turkey.com tvnet.lv twc.com typemail.com u2club.com uae.ac -freemail_domains ubbi.com ubbi.com.br uboot.com ugeek.com uk2.net uk2net.com ukr.net -freemail_domains ukrpost.net ukrpost.ua uku.co.uk ulimit.com ummah.org unbounded.com -freemail_domains unicum.de unimail.mn unitedemailsystems.com universal.pt -freemail_domains universia.cl universia.edu.ve universia.es universia.net.co universia.net.mx -freemail_domains universia.pr universia.pt universiabrasil.net unofree.it uol.com.ar -freemail_domains uol.com.br uole.com uolmail.com uomail.com uraniomail.com urbi.com.br -freemail_domains ureach.com usanetmail.com userbeam.com utah.usa.com -freemail_domains uyuyuy.com v-sexi.com v3mail.com vegetarisme.be velnet.com velocall.com -freemail_domains vercorreo.com verizonmail.com vermont.usa.com verticalheaven.com -freemail_domains veryfast.biz veryspeedy.net vfemail.net vietmedia.com vip.gr virgilio.it -freemail_domains virgin.net virginia.usa.com virtual-mail.com visitmail.com visto.com -freemail_domains vivelared.com vjtimail.com vnn.vn vsnl.com vsnl.net vodamail.co.za voila.fr volkermord.com vosforums.com vodafone.* -freemail_domains w.cn walla.com walla.co.il wallet.com wam.co.za wanex.ge wap.hu -freemail_domains wapda.com wapicode.com wappi.com warpmail.net washington.usa.com wassup.com -freemail_domains waterloo.com waumail.com wazmail.com wearab.net web-mail.com.ar web.de -freemail_domains web.nl web2mail.com webaddressbook.com webbworks.com webcity.ca webdream.com -freemail_domains webemaillist.com webindia123.com webinfo.fi webjump.com webl-3.br.inter.net -freemail_domains webmail.co.yu webmail.co.za webmails.com webmailv.com webpim.cc -freemail_domains webspawner.com webstation.com websurfer.co.za webtopmail.com webtribe.net -freemail_domains webtv.net weedmail.com weekonline.com weirdness.com westvirginia.usa.com -freemail_domains whale-mail.com whipmail.com who.net whoever.com wildcats.com wildmail.com -freemail_domains williams.net.ar winning.com winningteam.com winwinhosting.com -freemail_domains wisconsin.usa.com witelcom.com witty.com wolverines.com wooow.it -freemail_domains workmail.co.za worldcrossing.com worldemail.com worldmedic.com -freemail_domains worldonline.de wowmail.com wp.pl wprost.pl wrongmail.com -freemail_domains wtonetwork.com wurtele.net www.com www.consulcredit.it wyoming.usa.com -freemail_domains x-mail.net xasa.com xemail.* xfreehosting.com xmail.net xmsg.com xnmsn.cn xoom.com xtra.co.nz xuite.net -freemail_domains xpectmore.com xrea.com xsmail.com xzapmail.com y7mail.com yahala.co.il -freemail_domains yaho.com yahoo.* yahoo.co*.* yalla.com.lb -freemail_domains ya.com yeah.net ya.ru yahoomail.com -freemail_domains yam.com yamal.info yandex.* yapost.com yawmail.com yebox.com yehey.com -freemail_domains yellow-jackets.com yellowstone.net yenimail.com yepmail.net yifan.net -freemail_domains ymail.com yopmail.com your-mail.com yours.com yourwap.com yyhmail.com z11.com z6.com -freemail_domains zednet.co.uk zeeman.nl ziplip.com zipmail.com.br zipmax.com -freemail_domains zmail.pt zmail.ru zona-andina.net zonai.com zoneview.net zonnet.nl -freemail_domains zoho.com zoomshare.com zoznam.sk zubee.com zuvio.com zwallet.com zworg.com -freemail_domains zybermail.com zzn.com - -# chinese numbers -freemail_domains 126.com 139.com 163.com 188.com 189.cn 263.net 9.cn - -# Vips -freemail_domains vip.126.com vip.163.com vip.188.com -freemail_domains vip.sina.com vip.sohu.com vip.sohu.net vip.tom.com vip.qq.com vipsohu.net - -# Bug 6903 - powered by VFEmail - 2013-02-19-AXB -freemail_domains clovermail.net mail-on.us chewiemail.com offcolormail.com powdermail.com tightmail.com toothandmail.com tushmail.com -freemail_domains openmail.cc expressmail.dk - -# Bug 6903 - powered by 5x2 Online 2013-02-19-AXB -freemail_domains 4xn.de 5x2.de 5x2.me aufdrogen.de auf-steroide.de -freemail_domains besser-als-du.de brainsurfer.de chillaxer.de cyberkriminell.de -freemail_domains danneben.so freemailen.de freemailn.de ist-der-mann.de -freemail_domains ist-der-wahnsinn.de ist-echt.so istecht.so ist-genialer.de -freemail_domains ist-schlauer.de ist-supersexy.de kann.so mag-spam.net -freemail_domains mega-schlau.de muss.so nerd4life.de ohne-drogen-gehts.net -freemail_domains on-steroids.de scheint.so staatsterrorist.de super-gerissen.de -freemail_domains unendlich-schlau.de vip-client.de will-keinen-spam.de -freemail_domains zu-geil.de - -# Bug 6903 - powered by Runbox - paid service, but offers 30 day free trial - 2013-02-19-AXB -freemail_domains runbox.* -freemail_domains rbox.me rbox.co - -freemail_domains tunome.com - -freemail_domains acatperson.com adogperson.com all4theskins.com -freemail_domains allsportsrock.com alwaysgrilling.com alwaysinthekitchen.com -freemail_domains alwayswatchingmovies.com alwayswatchingtv.com asylum.com -freemail_domains basketball-email.com beabookworm.com beagolfer.com beahealthnut.com -freemail_domains believeinliberty.com bestcoolcars.com bestjobcandidate.com besure2vote.com -freemail_domains bigtimecatperson.com bigtimedogperson.com bigtimereader.com -freemail_domains bigtimesportsfan.com blackvoices.com capsfanatic.com capshockeyfan.com -freemail_domains capsred.com car-nut.net cat-person.com catpeoplerule.com chat-with-me.com -freemail_domains cheatasrule.com crazy4baseball.com crazy4homeimprovement.com crazy4mail.com -freemail_domains crazyaboutfilms.net crazycarfan.com crazyforemail.com crazymoviefan.com -freemail_domains descriptivemail.com differentmail.com dog-person.com dogpeoplerule.com -freemail_domains easydoesit.com expertrenovator.com expressivemail.com fanaticos.com -freemail_domains fanofbooks.com fanofcomputers.com fanofcooking.com fanoftheweb.com -freemail_domains fieldmail.com fleetmail.com focusedonprofits.com focusedonreturns.com -freemail_domains futboladdict.com games.com getintobooks.com hail2theskins.com hitthepuck.com -freemail_domains i-dig-movies.com i-love-restaurants.com idigcomputers.com -freemail_domains idigelectronics.com idigvideos.com ilike2helpothers.com ilike2invest.com -freemail_domains ilike2workout.com ilikeelectronics.com ilikeworkingout.com -freemail_domains ilovehomeprojects.com iloveourteam.com iloveworkingout.com in2autos.net -freemail_domains interestedinthejob.com intomotors.com iwatchrealitytv.com lemondrop.com -freemail_domains love2exercise.com love2workout.com lovefantasysports.com lovetoexercise.com -freemail_domains luvfishing.com luvgolfing.com luvsoccer.com -freemail_domains mail4me.com majorgolfer.com majorshopaholic.com majortechie.com mcom.com -freemail_domains motor-nut.com moviefan.com mycapitalsmail.com mycatiscool.com -freemail_domains myfantasyteamrules.com myteamisbest.com netbusiness.com news-fanatic.com -freemail_domains newspaperfan.com onlinevideosrock.com realbookfan.com realhealthnut.com -freemail_domains realitytvaddict.net realitytvnut.com reallyintomusic.com realtravelfan.com -freemail_domains redskinscheer.com redskinsfamily.com redskinsfancentral.com redskinshog.com -freemail_domains redskinsrule.com redskinsspecialteams.com redskinsultimatefan.com -freemail_domains scoutmail.com skins4life.com stargate2.com stargateatlantis.com -freemail_domains stargatefanclub.com stargatesg1.com stargateu.com switched.com -freemail_domains t-online.de thegamefanatic.com total-techie.com totalfoodnut.com -freemail_domains totally-into-cooking.com totallyintobaseball.com totallyintobasketball.com -freemail_domains totallyintocooking.com totallyintofootball.com totallyintogolf.com -freemail_domains totallyintohockey.com totallyintomusic.com totallyintoreading.com -freemail_domains totallyintosports.com totallyintotravel.com totalmoviefan.com -freemail_domains travel2newplaces.com tvchannelsurfer.com ultimateredskinsfan.com -freemail_domains videogamesrock.com volunteeringisawesome.com wayintocomputers.com -freemail_domains whatmail.com when.com wild4music.com wildaboutelectronics.com -freemail_domains workingaroundthehouse.com workingonthehouse.com writesoon.com xmasmail.com - -# irq.ir / 091030 - -freemail_domains arab.ir denmark.ir egypt.ir icq.ir ir.ae iraq.ir ire.ir ireland.ir irr.ir -freemail_domains jpg.ir ksa.ir kuwait.ir london.ir paltalk.ir spain.ir sweden.ir tokyo.ir - - -# scraped http://www.zemskov.net/free-email-domains.html 2013-10-18-khopesh - -# bigmailbox.com -freemail_domains 111mail.com 123iran.com 37.com 420email.com 4degreez.com -freemail_domains 4-music-today.com actingbiz.com allhiphop.com anatomicrock.com -freemail_domains animeone.com asiancutes.com a-teens.net ausi.com autoindia.com -freemail_domains autopm.com barriolife.com b-boy.com beautifulboy.com bgay.com -freemail_domains bicycledata.com bicycling.com bigheavyworld.com bigmailbox.net -freemail_domains bikerheaven.net bikermail.com billssite.com -freemail_domains blackandchristian.com blackcity.net blackvault.com bmxtrix.com -freemail_domains boarderzone.com boatnerd.com bolbox.com bongmail.com bowl.com -freemail_domains butch-femme.org byke.com calle22.com cannabismail.com -freemail_domains catlovers.com certifiedbitches.com championboxing.com -freemail_domains chatway.com chillymail.com classprod.com classycouples.com -freemail_domains congiu.net coolshit.com corpusmail.com cyberunlimited.org -freemail_domains cycledata.com darkfear.com darkforces.com dirtythird.com -freemail_domains dopefiends.com draac.com drakmail.net dr-dre.com dreamstop.com -freemail_domains egypt.net emailfast.com envirocitizen.com escapeartist.com -freemail_domains ezsweeps.com famous.as farts.com feelingnaughty.com -freemail_domains firemyst.com freeonline.com fudge.com funkytimes.com -freemail_domains gamerssolution.com gazabo.net glittergrrrls.com goatrance.com -freemail_domains goddess.com gohip.com gospelcity.com gothicgirl.com -freemail_domains grapemail.net greatautos.org guy.com haitisurf.com -freemail_domains happyhippo.com hateinthebox.com houseofhorrors.com hugkiss.com -freemail_domains hullnumber.com idunno4recipes.com ihatenetscape.com -freemail_domains intimatefire.com irow.com jazzemail.com juanitabynum.com -freemail_domains kanoodle.com kickboxing.com kidrock.com kinkyemail.com -freemail_domains kool-things.com latinabarbie.com latinogreeks.com leesville.com -freemail_domains loveemail.com lowrider.com lucky7lotto.net madeniggaz.net -freemail_domains mailbomb.com marillion.net megarave.com mofa.com motley.com -freemail_domains music.com musician.net musicsites.com netbroadcaster.com -freemail_domains netfingers.com net-surf.com nocharge.com operationivy.com -freemail_domains paidoffers.net pcbee.com persian.com petrofind.com -freemail_domains phunkybitches.com pikaguam.com pinkcity.net pitbullmail.com -freemail_domains planetsmeg.com poop.com poormail.com potsmokersnet.com -freemail_domains primetap.com project420.com prolife.net puertoricowow.com -freemail_domains puppetweb.com rapstar.com rapworld.com rastamall.com ratedx.net -freemail_domains ravermail.com relapsecult.com remixer.com rockeros.com -freemail_domains romance106fm.com singalongcenter.com sketchyfriends.com -freemail_domains slayerized.com smartstocks.com soulja-beatz.org -freemail_domains specialoperations.com speedymail.net spells.com -freemail_domains streetracing.com subspacemail.com sugarray.com -freemail_domains superbikeclub.com superintendents.net surfguiden.com -freemail_domains sweetwishes.com tattoodesign.com teamster.net teenchatnow.com -freemail_domains the5thquarter.com theblackmarket.com tombstone.ws troamail.org -freemail_domains u2tours.com vitalogy.org whatisthis.com wrestlezone.com -# gawab.com -freemail_domains abha.cc agadir.cc ahsa.ws ajman.cc ajman.us ajman.ws albaha.cc -freemail_domains algerie.cc alriyadh.cc amman.cc aqaba.cc arar.ws aswan.cc -freemail_domains baalbeck.cc bahraini.cc banha.cc bizerte.cc blida.info -freemail_domains buraydah.cc cameroon.cc dhahran.cc dhofar.cc djibouti.cc -freemail_domains dominican.cc eritrea.cc falasteen.cc fujairah.cc fujairah.us -freemail_domains fujairah.ws gabes.cc gafsa.cc giza.cc guinea.cc hamra.cc -freemail_domains hasakah.com hebron.tv homs.cc ibra.cc irbid.ws ismailia.cc -freemail_domains jadida.cc jadida.org jerash.cc jizan.cc jouf.cc kairouan.cc -freemail_domains karak.cc khaimah.cc khartoum.cc khobar.cc kuwaiti.tv -freemail_domains kyrgyzstan.cc latakia.cc lebanese.cc lubnan.cc lubnan.ws -freemail_domains madinah.cc maghreb.cc manama.cc mansoura.tv marrakesh.cc -freemail_domains mascara.ws meknes.cc muscat.tv muscat.ws nabeul.cc nabeul.info -freemail_domains nablus.cc nador.cc najaf.cc omani.ws omdurman.cc oran.cc -freemail_domains oued.info oued.org oujda.biz oujda.cc pakistani.ws palmyra.cc -freemail_domains palmyra.ws portsaid.cc qassem.cc quds.cc rabat.cc rafah.cc -freemail_domains ramallah.cc safat.biz safat.info safat.us safat.ws salalah.cc -freemail_domains salmiya.biz sanaa.cc seeb.cc sfax.ws sharm.cc sinai.cc siria.cc -freemail_domains sousse.cc sudanese.cc suez.cc tabouk.cc tajikistan.cc -freemail_domains tangiers.cc tanta.cc tayef.cc tetouan.cc timor.cc tunisian.cc -freemail_domains urdun.cc yanbo.cc yemeni.cc yunus.cc zagazig.cc zambia.cc -# other -freemail_domains 5005.lv a.org.ua bmx.lv company.org.ua coolmail.ru dino.lv -freemail_domains eclub.lv e-mail.am fit.lv hacker.am human.lv iphon.biz -freemail_domains latchess.com loveis.lv lv-inter.net pookmail.com sexriga.lv - -# Microsoft's new service 2013-10-18-khopesh -freemail_domains *.onmicrosoft.com - - -endif - diff --git a/resources/spamassassin/20_freemail_mailcom_domains.cf b/resources/spamassassin/20_freemail_mailcom_domains.cf deleted file mode 100644 index 0d946ec0..00000000 --- a/resources/spamassassin/20_freemail_mailcom_domains.cf +++ /dev/null @@ -1,60 +0,0 @@ -# SpamAssassin - Mail.com Freemail domains file -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -# List contains commonly abused end user mail providers -# "freemail" is solely used for label purposes. - -# This dedicated list contains domains provided by mail.com - -# Updated 2014-09-17-axb - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - -freemail_domains accountant.com acdcfan.com activist.com adexec.com africamail.com aircraftmail.com allergist.com alumni.com alumnidirector.com angelic.com appraiser.net archaeologist.com arcticmail.com artlover.com asia-mail.com asia.com atheist.com auctioneer.net australiamail.com -freemail_domains bartender.net bellair.net berlin.com bikerider.com birdlover.com blader.com boardermail.com brazilmail.com brew-master.com brew-meister.com bsdmail.com -freemail_domains californiamail.com cash4u.com catlover.com cheerful.com chef.net chemist.com chinamail.com clerk.com clubmember.org collector.org columnist.com comic.com computer4u.com consultant.com contractor.net coolsite.net counsellor.com cutey.com cyber-wizard.com cyberdude.com cybergal.com cyberservices.com -freemail_domains dallasmail.com dbzmail.com deliveryman.com diplomats.com disciples.com discofan.com disposable.com doctor.com doglover.com doramail.com dr.com dublin.com dutchmail.com -freemail_domains elvisfan.com email.com engineer.com englandmail.com europe.com europemail.com execs.com -freemail_domains fastservice.com financier.com fireman.net -freemail_domains galaxyhit.com gardener.com geologist.com germanymail.com graduate.org graphic-designer.com greenmail.net groupmail.com -freemail_domains hackermail.com hairdresser.net hilarious.com hiphopfan.com homemail.com hot-shot.com housemail.com humanoid.net -freemail_domains iname.acom iname.com innocent.com inorbit.com instruction.com instructor.net insurer.com irelandmail.com israelmail.com italymail.com -freemail_domains job4u.com journalist.com -freemail_domains keromail.com kissfans.com kittymail.com koreamail.com -freemail_domains legislator.com linuxmail.org lobbyist.com lovecat.com -freemail_domains madonnafan.com mail-me.com mail.com marchmail.com metalfan.com mexicomail.com minister.com moscowmail.com munich.com musician.org muslim.com myself.com -freemail_domains net-shopping.com ninfan.com nonpartisan.com null.net nycmail.com -freemail_domains oath.com optician.com orthodontist.net -freemail_domains pacific-ocean.com pacificwest.com pediatrician.com petlover.com photographer.net physicist.net planetmail.com planetmail.net polandmail.com politician.com post.com presidency.com priest.com programmer.net protestant.com publicist.com -freemail_domains qualityservice.com -freemail_domains radiologist.net ravemail.com realtyagent.com reborn.com reggaefan.com registerednurses.com reincarnate.com religious.com repairman.com representative.com rescueteam.com rocketship.com -freemail_domains safrica.com saintly.com salesperson.net samerica.com sanfranmail.com scientist.com scotlandmail.com secretary.net snakebite.com socialworker.net sociologist.com solution4u.com songwriter.net spainmail.com surgical.net swedenmail.com swissmail.com -freemail_domains teachers.org tech-center.com techie.com technologist.com theplate.com therapist.net toke.com toothfairy.com torontomail.com tvstar.com -freemail_domains umpire.com usa.com uymail.com -freemail_domains webname.com worker.com workmail.com writeme.com - -endif - - diff --git a/resources/spamassassin/20_head_tests.cf b/resources/spamassassin/20_head_tests.cf deleted file mode 100644 index d68f0f6f..00000000 --- a/resources/spamassassin/20_head_tests.cf +++ /dev/null @@ -1,614 +0,0 @@ -# SpamAssassin rules file: header tests -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -########################################################################### - -# partial messages; currently-theoretical attack -# unsurprisingly this hits 0/0 right now. -header FRAGMENTED_MESSAGE Content-Type =~ /\bmessage\/partial/i -describe FRAGMENTED_MESSAGE Partial message -tflags FRAGMENTED_MESSAGE userconf - -########################################################################### - -header FROM_BLANK_NAME From =~ /(?:\s|^)"" <\S+>/i -describe FROM_BLANK_NAME From: contains empty name - -########################################################################### -# numeric address rules, these are written to avoid overlap with each other - -header __FROM_ENDS_IN_NUMS From:addr =~ /\D\d{8,}\@/i - -header FROM_STARTS_WITH_NUMS From:addr =~ /^\d{3,50}[^0-9\@]/ -describe FROM_STARTS_WITH_NUMS From: starts with several numbers - -# don't match US/Canada phone numbers: 10 digits optionally preceded by a "1" -header __FROM_ALL_NUMS From:addr =~ /^(?:\d{1,9}|[02-9]\d{10}|\d{12,})@/ - -########################################################################### - -header FROM_OFFERS From:addr =~ /\@\S*offers(?![eo]n\b)/i -describe FROM_OFFERS From address is "at something-offers" - -header FROM_NO_USER From =~ /(?:^\@|<\@| \@[^\)<]*$|<>)/ [if-unset: unset@unset.unset] -describe FROM_NO_USER From: has no local-part before @ sign - -# also 100% valid -# bug 6149: avoid common .jp false positives -header __PLING_QUERY Subject =~ /\?.*!|!.*\?/ -meta PLING_QUERY (__PLING_QUERY && !__ISO_2022_JP_DELIM) -describe PLING_QUERY Subject has exclamation mark and question mark - - - - -header MSGID_SPAM_CAPS Message-ID =~ /^\s*/ -describe MSGID_SPAM_LETTERS Spam tool Message-Id: (letters variant) - - - -# negative lookahead exempts this MUA from circa 1997-2000 -# X-Mailer: Microsoft Outlook Express 4.71.1712.3 -# Message-ID: <01bd45da$2649cdc0$LocalHost@andrew> -header __MSGID_DOLLARS_OK MESSAGEID =~ /<[0-9a-f]{4,}\$[0-9a-f]{4,}\$[0-9a-f]{4,}\@\S+>/ -header __MSGID_DOLLARS_MAYBE MESSAGEID =~ /<\w{4,}\$\w{4,}\$(?!localhost)\w{4,}\@\S+>/i -meta MSGID_DOLLARS_RANDOM __MSGID_DOLLARS_MAYBE && !__MSGID_DOLLARS_OK - -# bit of a ratware rule, but catches a bit more than just the one ratware -header __MSGID_RANDY Message-ID =~ /<[a-z\d][a-z\d\$-]{10,29}[a-z\d]\@[a-z\d][a-z\d.]{3,12}[a-z\d]>/ -# heuristic to eliminate most good Message-ID formats -header __MSGID_OK_HEX Message-ID =~ /\b[a-f\d]{8}\b/ -header __MSGID_OK_DIGITS Message-ID =~ /\d{10}/ -header __MSGID_OK_HOST Message-ID =~ /\@(?:\D{2,}|(?:\d{1,3}\.){3}\d{1,3})>/ -meta MSGID_RANDY (__MSGID_RANDY && !(__MSGID_OK_HEX || __MSGID_OK_DIGITS || __MSGID_OK_HOST)) -describe MSGID_RANDY Message-Id has pattern used in spam - -# bug 3395 -header MSGID_YAHOO_CAPS Message-ID =~ /<[A-Z]+\@yahoo.com>/ -describe MSGID_YAHOO_CAPS Message-ID has ALLCAPS@yahoo.com - -########################################################################### - -header __AT_AOL_MSGID MESSAGEID =~ /\@aol\.com\b/i -header __FROM_AOL_COM From =~ /\@aol\.com\b/i -meta FORGED_MSGID_AOL (__AT_AOL_MSGID && !__FROM_AOL_COM) -describe FORGED_MSGID_AOL Message-ID is forged, (aol.com) - -header __AT_EXCITE_MSGID MESSAGEID =~ /\@excite\.com\b/i -header __MY_RCVD_EXCITE Received =~ /\.excite\.com\b/i -meta FORGED_MSGID_EXCITE (__AT_EXCITE_MSGID && !__MY_RCVD_EXCITE) -describe FORGED_MSGID_EXCITE Message-ID is forged, (excite.com) - -header __AT_HOTMAIL_MSGID MESSAGEID =~ /\@hotmail\.com\b/i -header __FROM_HOTMAIL_COM From =~ /\@hotmail\.com\b/i -meta FORGED_MSGID_HOTMAIL (__AT_HOTMAIL_MSGID && (!__FROM_HOTMAIL_COM && !__FROM_MSN_COM && !__FROM_YAHOO_COM)) -describe FORGED_MSGID_HOTMAIL Message-ID is forged, (hotmail.com) - -header __AT_MSN_MSGID MESSAGEID =~ /\@msn\.com\b/i -header __FROM_MSN_COM From =~ /\@msn\.com\b/i -meta FORGED_MSGID_MSN (__AT_MSN_MSGID && (!__FROM_MSN_COM && !__FROM_HOTMAIL_COM && !__FROM_YAHOO_COM)) -describe FORGED_MSGID_MSN Message-ID is forged, (msn.com) - -header __AT_YAHOO_MSGID MESSAGEID =~ /\@yahoo\.com\b/i -header __FROM_YAHOO_COM From =~ /\@yahoo\.com\b/i -meta FORGED_MSGID_YAHOO (__AT_YAHOO_MSGID && !__FROM_YAHOO_COM) -describe FORGED_MSGID_YAHOO Message-ID is forged, (yahoo.com) - -########################################################################### - -header __MSGID_BEFORE_RECEIVED ALL =~ /^Message-Id:.*?^Received:/msi -header __MSGID_BEFORE_OKAY Message-Id =~ /\@[a-z0-9.-]+\.(?:yahoo|wanadoo)(?:\.[a-z]{2,3}){1,2}>/ - -meta MSGID_FROM_MTA_HEADER (__MSGID_BEFORE_RECEIVED && !__MSGID_BEFORE_OKAY && !__FROM_HOTMAIL_COM) -describe MSGID_FROM_MTA_HEADER Message-Id was added by a relay - - - -header MSGID_SHORT MESSAGEID =~ /^.{1,15}$|<.{0,4}\@/ -describe MSGID_SHORT Message-ID is unusually short - -#DEMOTED TO SANDBOX - 2012-03-21 -#header MSGID_MULTIPLE_AT MESSAGEID =~ /<[^>]*\@[^>]*\@/ -#describe MSGID_MULTIPLE_AT Message-ID contains multiple '@' characters - -########################################################################### - -header DATE_SPAMWARE_Y2K Date =~ /^[A-Z][a-z]{2}, \d\d [A-Z][a-z]{2} [0-6]\d \d\d:\d\d:\d\d [A-Z]{3}$/ -describe DATE_SPAMWARE_Y2K Date header uses unusual Y2K formatting - -# as noted on the dev@ list, ":60" is valid for seconds when there's a leap -# second (12/31/2005 for instance), so let's accept that as valid. ISO 8601 -# apparently allows for it. -# there were a few whitespace issues in the original RE, and I wanted to avoid my -# two common, but yes invalid, date headers. specifically / \(GMT\)$/ and -# / 0000 GMT$/. dos has / "GMT"$/ - tvd -# 2.229 2.7267 0.0517 0.981 0.86 0.00 INVALID_DATE -# 2.263 2.7486 0.1368 0.953 0.78 0.00 INVALID_DATE_OLD -# -# WRT the tests, remember that ok and fail are reversed -- so valid dates -# should be "fail" and invalid dates should be "ok". -header INVALID_DATE Date !~ /^\s*(?:(?i:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?\s*(?:[12]\d|3[01]|0?[1-9])\s+(?i:Jan|Feb|Ma[ry]|Apr|Ju[nl]|Aug|Sep|Oct|Nov|Dec)\s+(?:19[7-9]\d|2\d{3})\s+(?:[01]?\d|2[0-3])\:[0-5]\d(?::(?:[0-5]\d|60))?(?:\s+[AP]M)?(?:\s+(?:[+-][0-9]{4}|UT|[A-Z]{2,3}T|0000 GMT|"GMT"))?(?:\s*\(.*\))?\s*$/ [if-unset: Wed, 31 Jul 2002 16:41:57 +0200] -describe INVALID_DATE Invalid Date: header (not RFC 2822) -test INVALID_DATE fail Sat, 31 Dec 2005 23:59:60 -0500 -test INVALID_DATE fail Wed, 31 Jul 2002 16:41:57 +0200 -test INVALID_DATE fail Sat, 31 Dec 2005 23:00:00 -test INVALID_DATE ok Sat, 31 Dec 2005 24:00:00 -0500 -test INVALID_DATE ok Thurs, 31 Jul 2002 16:41:57 +0200 - -# allow +1300, NZ timezone -header INVALID_DATE_TZ_ABSURD Date =~ /[-+](?!(?:0\d|1[0-4])(?:[03]0|[14]5))\d{4}$/ -describe INVALID_DATE_TZ_ABSURD Invalid Date: header (timezone does not exist) - -header INVALID_TZ_CST ALL =~ /[+-]\d\d[30]0(?, see SpamAssassin-talk list 2003-03 -# quinlan: 2003-03-23 here are more generic Japanese iso-2022-jp codes -# ("not yet acceptance" or "email") + "announcement" -# FWIW, according to Peter Evans, this should be sufficient to catch the -# UCE tag and a common attempt at evasion (using the "sue" instead of -# "mi" Chinese character). 2006-10-12: updated by bug 4021. -header JAPANESE_UCE_SUBJECT Subject =~ /\e\$B.*(?:L\$>5Bz|EE;R%a!<%k)(?:8x|9-)9p/ -describe JAPANESE_UCE_SUBJECT Subject contains a Japanese UCE tag - -# check body for "shou nin daku kou koku" UCE tag (bug 4021) -body __JAPANESE_UCE_BODY /(?:L\$>5Bz|EE;R%a!<%k)(?:8x|9-)9p/ - -meta JAPANESE_UCE_BODY (__ISO_2022_JP_DELIM && __JAPANESE_UCE_BODY) -describe JAPANESE_UCE_BODY Body contains Japanese UCE tag - -# quinlan: "advertisement" in Russian KOI8-R -# (no longer common, but worth noting in future) -#header RUSSIAN_UCE_SUBJECT Subject =~ /\xf0\xe5\xea\xeb\xe0\xec\xf3/ -#describe RUSSIAN_UCE_SUBJECT Subject contains a Russian UCE tag - -# Korean UCE Subject: lines are usually 8-bit, but are occasionally encoded -# with quoted-printable or base64. -# -# \xbc\xba\xc0\xce means "adult" -# \xb1\xa4\xb0\xed means "advertisement" -# \xc1\xa4\xba\xb8 means "information" -# \xc8\xab\xba\xb8 means "publicity" -# -# Each two byte sequence is one Korean letter; the spaces and periods are -# sometimes used to obscure the words. \xb1\xa4\xb0\xed is the most common -# tag and is sometimes very obscured so we look harder. -# -header KOREAN_UCE_SUBJECT Subject =~ /[({[<][. ]*(?-i:\xbc\xba[. ]*\xc0\xce[. ]*)?(?-i:\xb1\xa4(?:[. ]*|[\x00-\x7f]{0,3})\xb0\xed|\xc1\xa4[. ]*\xba\xb8|\xc8\xab[. ]*\xba\xb8)[. ]*[)}\]>]/ -describe KOREAN_UCE_SUBJECT Subject: contains Korean unsolicited email tag - -########################################################################### - -# two reliable signatures -header __DOUBLE_IP_SPAM_1 Received =~ /from \[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\] by \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} with/ -header __DOUBLE_IP_SPAM_2 Received =~ /from\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+by\s+\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3};/ -# loose match -header __DOUBLE_IP_LOOSE Received =~ /(?:\b(?:from|by)\b.{1,4}\b\d{1,3}[._-]\d{1,3}[._-]\d{1,3}[._-]\d{1,3}(? 1) -describe MULTI_FORGED Received headers indicate multiple forgeries - -header NONEXISTENT_CHARSET Content-Type =~ /charset=.?DEFAULT/ -describe NONEXISTENT_CHARSET Character set doesn't exist - -header __HAS_MESSAGE_ID exists:Message-Id -priority __HAS_MESSAGE_ID -2000 # Bug 8078 -meta MISSING_MID !__HAS_MESSAGE_ID -describe MISSING_MID Missing Message-Id: header - -header __HAS_DATE exists:Date -priority __HAS_DATE -2000 # Bug 8078 -meta MISSING_DATE !__HAS_DATE -describe MISSING_DATE Missing Date: header - -header __HAS_SUBJECT exists:Subject -priority __HAS_SUBJECT -2000 # Bug 8078 -meta MISSING_SUBJECT !__HAS_SUBJECT -describe MISSING_SUBJECT Missing Subject: header - -# bug 6353 -header __HAS_FROM exists:From -priority __HAS_FROM -2000 # Bug 8078 -meta MISSING_FROM !__HAS_FROM -describe MISSING_FROM Missing From: header - -# bug 6149: avoid common .jp false positives -header __GAPPY_SUBJECT Subject =~ /\b(?:[a-z]([-_. =~\/:,*!\@\#\$\%\^&+;\"\'<>\\])\1{0,2}){4}/i -meta GAPPY_SUBJECT (__GAPPY_SUBJECT && !__ISO_2022_JP_DELIM) -describe GAPPY_SUBJECT Subject: contains G.a.p.p.y-T.e.x.t - -### header existence tests (description is added automatically) - -# X-Fix example: NTMail fixed non RFC822 compliant EMail message -# -# X-PMFLAGS is all caps -# -# Headers that seem to only be used by a single spamming software and -# are found together in the same message: -# 1. X-MailingID and X-ServerHost -# 2. X-Stormpost-To and X-List-Unsubscribe -# -# not spammish: X-EM-Registration, X-EM-Version, X-Antiabuse, X-List-Host, -# X-Message-Id -# bad FP rate: Comment, Date-warning - -header PREVENT_NONDELIVERY exists:Prevent-NonDelivery-Report -describe PREVENT_NONDELIVERY Message has Prevent-NonDelivery-Report header - -header X_IP exists:X-IP -describe X_IP Message has X-IP header - -header __HAS_MIMEOLE exists:X-MimeOLE -header __HAS_MSMAIL_PRI exists:X-MSMail-Priority -header __HAS_SQUIRRELMAIL_IN_MAILER X-Mailer =~ /SquirrelMail\b/ -# Ever growing Office version list without X-MimeOLE, bug 6346, 7122, 7463. -header __HAS_OFFICE1214_IN_MAILER X-Mailer =~ /^Microsoft (?:Office )?Outlook 1[2456]\.0/ -# CGP MAPI module fingerprint, to protect from MISSING_MIMEOLE -header __HAS_CGP_MAPI_IN_MAILER X-Mailer =~ /CommuniGate Pro MAPI/ -meta MISSING_MIMEOLE (__HAS_MSMAIL_PRI && !__HAS_MIMEOLE && !__HAS_SQUIRRELMAIL_IN_MAILER && !__HAS_OFFICE1214_IN_MAILER && !__HAS_CGP_MAPI_IN_MAILER && !__HDR_RCVD_TONLINEDE && !__MIME_BASE64 && !__DKIM_EXISTS) -describe MISSING_MIMEOLE Message has X-MSMail-Priority, but no X-MimeOLE - -header __HAS_X_MAILER exists:X-Mailer - -header __IS_EXCH X-MimeOLE =~ /Produced By Microsoft Exchange V/ - -header SUBJ_AS_SEEN Subject =~ /\bAs Seen/i -describe SUBJ_AS_SEEN Subject contains "As Seen" - -header SUBJ_DOLLARS Subject =~ /^\$[0-9.,]+\b/ -describe SUBJ_DOLLARS Subject starts with dollar amount - - - - - - -#DISABLING DUE TO POOR S/O 2012-09-27 -#header SUBJ_YOUR_DEBT Subject =~ /Your (?:Bills|Debt|Credit)/i -#describe SUBJ_YOUR_DEBT Subject contains "Your Bills" or similar - -header SUBJ_YOUR_FAMILY Subject =~ /Your Family/i -describe SUBJ_YOUR_FAMILY Subject contains "Your Family" - - -# the real services never HELO as 'foo.com', instead 'mail.foo.com' or -# something like that. Note: be careful when expanding this... legit dotcom -# HELOers include: hotmail.com, drizzle.com, lockergnome.com. -header RCVD_FAKE_HELO_DOTCOM Received =~ /^from (?:msn|yahoo|yourwebsite|lycos|excite|cs|aol|localhost|koreanmail|allexecs|mydomain|juno|eudoramail|compuserve|desertmail|excite|caramail)\.com \(/m -describe RCVD_FAKE_HELO_DOTCOM Received contains a faked HELO hostname - -header SUBJECT_DIET Subject =~ /\bLose .*(?:pounds|lbs|weight)/i -describe SUBJECT_DIET Subject talks about losing pounds - - -# MIME boundary tests; spam tools use distinctive patterns. -header MIME_BOUND_DD_DIGITS Content-Type =~ /boundary=\"--\d+\"/ -describe MIME_BOUND_DD_DIGITS Spam tool pattern in MIME boundary -header MIME_BOUND_DIGITS_15 Content-Type =~ /boundary=\"\d{15,}\"/ -describe MIME_BOUND_DIGITS_15 Spam tool pattern in MIME boundary -header MIME_BOUND_MANY_HEX Content-Type =~ /boundary="[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}"/ -describe MIME_BOUND_MANY_HEX Spam tool pattern in MIME boundary - -# note: the first alternation is anchored for speed -header TO_MALFORMED To !~ /(?:^|[^\S"])(?:(?:\"[^\"]+\"|\S+)\@\S+\.\S+|^\s*.+:\s*;|^\s*\"[^\"]+\":\s*;|^\s*\([^\)]*\)\s*$|<\S+(?:\!\S+){1,}>|^\s*$)/ [if-unset: unset@unset.unset] -describe TO_MALFORMED To: has a malformed address - -header __CD exists:Content-Disposition -header __CT exists:Content-Type -header __CTE exists:Content-Transfer-Encoding -header __MIME_VERSION exists:MIME-Version -header __CT_TEXT_PLAIN Content-Type =~ /^text\/plain\b/i -meta MIME_HEADER_CTYPE_ONLY (!__CD && !__CTE && __CT && !__MIME_VERSION && !__CT_TEXT_PLAIN) -describe MIME_HEADER_CTYPE_ONLY 'Content-Type' found without required MIME headers - -header WITH_LC_SMTP Received =~ /\swith\ssmtp;\s/ -describe WITH_LC_SMTP Received line contains spam-sign (lowercase smtp) - - -header SUBJ_BUY Subject =~ /^buy/i -describe SUBJ_BUY Subject line starts with Buy or Buying - -# seems to be ratware -header RCVD_AM_PM Received =~ /; [A-Z][a-z][a-z], \d{1,2} \d{4} \d{1,2}:\d\d:\d\d [AP]M [+-]\d{4}/ -describe RCVD_AM_PM Received headers forged (AM/PM) - -header __USER_AGENT_MSN X-Mailer =~ /^MSN Explorer / - -# host no longer exists according to administrator -header FAKE_OUTBLAZE_RCVD Received =~ /\.mr\.outblaze\.com/ -describe FAKE_OUTBLAZE_RCVD Received header contains faked 'mr.outblaze.com' - - -# thanks to David Ritz for passing this on -header UNCLOSED_BRACKET ALL =~ /\[\d+\r?\n/s -describe UNCLOSED_BRACKET Headers contain an unclosed bracket - -header FROM_DOMAIN_NOVOWEL From =~ /\@\S*[bcdfgjklmnpqrstvwxz]{7}/i -describe FROM_DOMAIN_NOVOWEL From: domain has series of non-vowel letters -tflags FROM_DOMAIN_NOVOWEL userconf # lock scores low - -header FROM_LOCAL_NOVOWEL From =~ /[bcdfgjklmnpqrstvwxz]{7}\S*\@/i -describe FROM_LOCAL_NOVOWEL From: localpart has series of non-vowel letters -tflags FROM_LOCAL_NOVOWEL userconf # lock scores low - -header FROM_LOCAL_HEX From =~ /[0-9a-f]{11}\S*\@/i -describe FROM_LOCAL_HEX From: localpart has long hexadecimal sequence - -header FROM_LOCAL_DIGITS From =~ /\d{11}\S*\@/i -describe FROM_LOCAL_DIGITS From: localpart has long digit sequence - -header __TOCC_EXISTS exists:ToCc - -header X_PRIORITY_CC ALL =~ /^X-Priority:[^\n]{0,80}^Cc:/msi -describe X_PRIORITY_CC Cc: after X-Priority: (bulk email fingerprint) - -# catch non-RFC2047 compliant messages -# Apple Mail has a bug where headers will have whitespace around the encoded -# text, so try to ignore that -header BAD_ENC_HEADER ALL:raw =~ /=\?[^?\s]+\?[^?\s]\?\s*[^?]+\s(?!\?=)/ -describe BAD_ENC_HEADER Message has bad MIME encoding in the header - - -header __ML1 Precedence =~ m{\b(list|bulk)\b}i -meta __ML2 __HAS_LIST_ID -header __ML3 exists:List-Post -header __ML4 exists:Mailing-List -header __ML5 Return-Path:addr =~ m{^([^\@]+-(request|bounces|admin|owner)|owner-[^\@]+)(\@|\z)}i -meta __VIA_ML __ML1 || __ML2 || __ML3 || __ML4 || __ML5 -describe __VIA_ML Mail from a mailing list - - -# some clueless mailing lists (like zmailer with an RFC822TABS option on) -# are replacing a leading space by a TAB in header fields From, To, -# Cc, Date (Bug 6429) -header __ML_TURNS_SP_TO_TAB Received =~ /\(ORCPT = 4.000000) - header __SUBJ_ILLEGAL_CHARS eval:check_illegal_chars('Subject','0.00','2') - meta SUBJ_ILLEGAL_CHARS (__SUBJ_ILLEGAL_CHARS && !__FROM_YAHOO_COM) - header FROM_ILLEGAL_CHARS eval:check_illegal_chars('From','0.20','2') - header __HEAD_ILLEGAL_CHARS eval:check_illegal_chars('ALL','0.010','2') - meta HEAD_ILLEGAL_CHARS __HEAD_ILLEGAL_CHARS && !__SUBJ_ILLEGAL_CHARS && !FROM_ILLEGAL_CHARS -endif -if (version < 4.000000) - meta __SUBJ_ILLEGAL_CHARS 0 - meta SUBJ_ILLEGAL_CHARS 0 - meta FROM_ILLEGAL_CHARS 0 - meta __HEAD_ILLEGAL_CHARS 0 - meta HEAD_ILLEGAL_CHARS 0 -endif - -describe SUBJ_ILLEGAL_CHARS Subject: has too many raw illegal characters -describe FROM_ILLEGAL_CHARS From: has too many raw illegal characters -describe HEAD_ILLEGAL_CHARS Headers have too many raw illegal characters - - ################################################################### - -# a forged Hotmail message; host HELO'd as hotmail.com, but it wasn't -header __FORGED_HOTMAIL_RCVD eval:check_for_forged_hotmail_received_headers() - -# this, by comparison is more common: from was @hotmail.com, but it wasn't -header FORGED_HOTMAIL_RCVD2 eval:check_for_no_hotmail_received_headers() -describe FORGED_HOTMAIL_RCVD2 hotmail.com 'From' address, but no 'Received:' - -header __FORGED_EUDORAMAIL_RCVD eval:check_for_forged_eudoramail_received_headers() - -header FORGED_YAHOO_RCVD eval:check_for_forged_yahoo_received_headers() -describe FORGED_YAHOO_RCVD 'From' yahoo.com does not match 'Received' headers - -if (version >= 3.004002) -header FORGED_GMAIL_RCVD eval:check_for_forged_gmail_received_headers() -describe FORGED_GMAIL_RCVD 'From' gmail.com does not match 'Received' headers -endif - -header __FORGED_JUNO_RCVD eval:check_for_forged_juno_received_headers() - - - -header SORTED_RECIPS eval:sorted_recipients() -describe SORTED_RECIPS Recipient list is sorted by address - -header SUSPICIOUS_RECIPS eval:similar_recipients('0.65','undef') -describe SUSPICIOUS_RECIPS Similar addresses in recipient list - -# this is a quite common false positive, as it's legal to remove a To but leave -# a CC. so don't score it high. -header MISSING_HEADERS eval:check_for_missing_to_header() -describe MISSING_HEADERS Missing To: header - -header DATE_IN_PAST_03_06 eval:check_for_shifted_date('-6', '-3') -describe DATE_IN_PAST_03_06 Date: is 3 to 6 hours before Received: date - -header DATE_IN_PAST_06_12 eval:check_for_shifted_date('-12', '-6') -describe DATE_IN_PAST_06_12 Date: is 6 to 12 hours before Received: date - -header DATE_IN_PAST_12_24 eval:check_for_shifted_date('-24', '-12') -describe DATE_IN_PAST_12_24 Date: is 12 to 24 hours before Received: date - -header DATE_IN_PAST_24_48 eval:check_for_shifted_date('-48', '-24') -describe DATE_IN_PAST_24_48 Date: is 24 to 48 hours before Received: date - - -header DATE_IN_PAST_96_XX eval:check_for_shifted_date('undef', '-96') -describe DATE_IN_PAST_96_XX Date: is 96 hours or more before Received: date - -header DATE_IN_FUTURE_03_06 eval:check_for_shifted_date('3', '6') -describe DATE_IN_FUTURE_03_06 Date: is 3 to 6 hours after Received: date - -header DATE_IN_FUTURE_06_12 eval:check_for_shifted_date('6', '12') -describe DATE_IN_FUTURE_06_12 Date: is 6 to 12 hours after Received: date - -header DATE_IN_FUTURE_12_24 eval:check_for_shifted_date('12', '24') -describe DATE_IN_FUTURE_12_24 Date: is 12 to 24 hours after Received: date - -header DATE_IN_FUTURE_24_48 eval:check_for_shifted_date('24', '48') -describe DATE_IN_FUTURE_24_48 Date: is 24 to 48 hours after Received: date - -header DATE_IN_FUTURE_48_96 eval:check_for_shifted_date('48', '96') -describe DATE_IN_FUTURE_48_96 Date: is 48 to 96 hours after Received: date - -#header DATE_IN_FUTURE_96_XX eval:check_for_shifted_date('96', 'undef') -meta DATE_IN_FUTURE_96_XX (0) -describe DATE_IN_FUTURE_96_XX Date: is 96 hours or more after Received: date - -header UNRESOLVED_TEMPLATE eval:check_unresolved_template() -describe UNRESOLVED_TEMPLATE Headers contain an unresolved template - -header SUBJ_ALL_CAPS eval:subject_is_all_caps() -describe SUBJ_ALL_CAPS Subject is all capitals - - -header LOCALPART_IN_SUBJECT eval:check_for_to_in_subject('user') -describe LOCALPART_IN_SUBJECT Local part of To: address appears in Subject - -header MSGID_OUTLOOK_INVALID eval:check_outlook_message_id() -describe MSGID_OUTLOOK_INVALID Message-Id is fake (in Outlook Express format) - -header HEADER_COUNT_CTYPE eval:check_header_count_range('Content-Type','2','999') -describe HEADER_COUNT_CTYPE Multiple Content-Type headers found - -endif - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - -# this is also mostly-theoretical, so allow 0 hits -header HEAD_LONG eval:check_msg_parse_flags('truncated_header') -describe HEAD_LONG Message headers are very long -tflags HEAD_LONG userconf - -header MISSING_HB_SEP eval:check_msg_parse_flags('missing_head_body_separator') -describe MISSING_HB_SEP Missing blank line between message header and body -tflags MISSING_HB_SEP userconf - -endif - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::RelayEval - -header __UNPARSEABLE_RELAY_COUNT eval:check_relays_unparseable() -tflags __UNPARSEABLE_RELAY_COUNT userconf - -meta UNPARSEABLE_RELAY (__UNPARSEABLE_RELAY_COUNT >= 1) -tflags UNPARSEABLE_RELAY userconf -describe UNPARSEABLE_RELAY Informational: message has unparseable relay lines - - -header RCVD_HELO_IP_MISMATCH eval:helo_ip_mismatch() -describe RCVD_HELO_IP_MISMATCH Received: HELO and IP do not match, but should - -# not used directly right now due to FPs; but CONFIRMED_FORGED turns it -# into a 1.0 S/O rule anyway, so that's not a problem ;) -# 2.626 3.6340 1.5251 0.704 0.34 1.44 FORGED_RCVD_TRAIL -# 0.956 3.3890 0.0000 1.000 0.98 4.30 CONFIRMED_FORGED -header __FORGED_RCVD_TRAIL eval:check_for_forged_received_trail() - -header NO_RDNS_DOTCOM_HELO eval:check_for_no_rdns_dotcom_helo() -describe NO_RDNS_DOTCOM_HELO Host HELO'd as a big ISP, but had no rDNS - -endif - -ifplugin Mail::SpamAssassin::Plugin::HeaderEval - -header __ENV_AND_HDR_FROM_MATCH eval:check_for_matching_env_and_hdr_from() - -endif - diff --git a/resources/spamassassin/20_html_tests.cf b/resources/spamassassin/20_html_tests.cf deleted file mode 100644 index d6aa9c46..00000000 --- a/resources/spamassassin/20_html_tests.cf +++ /dev/null @@ -1,239 +0,0 @@ -# SpamAssassin rules file: HTML tests -# -# Please don't modify this file as your changes will be overwritten with -# the next update. Use @@LOCAL_RULES_DIR@@/local.cf instead. -# See 'perldoc Mail::SpamAssassin::Conf' for details. -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -# HTML parser tests -# -# please sort these by eval type then name - -meta HTML_SHORT_LINK_IMG_1 __HTML_LENGTH_0000_1024 && __HTML_LINK_IMAGE -meta HTML_SHORT_LINK_IMG_2 __HTML_LENGTH_1024_1536 && __HTML_LINK_IMAGE -meta HTML_SHORT_LINK_IMG_3 __HTML_LENGTH_1536_2048 && __HTML_LINK_IMAGE -describe HTML_SHORT_LINK_IMG_1 HTML is very short with a linked image -describe HTML_SHORT_LINK_IMG_2 HTML is very short with a linked image -describe HTML_SHORT_LINK_IMG_3 HTML is very short with a linked image - - -meta HTML_SHORT_CENTER (__HTML_LENGTH_384 && __TAG_EXISTS_CENTER) -describe HTML_SHORT_CENTER HTML is very short with CENTER tag - - -meta HTML_TITLE_SUBJ_DIFF __HTML_TITLE_SUBJ_DIFF && !__MIME_ATTACHMENT - -meta HTML_CHARSET_FARAWAY (__HTML_CHARSET_FARAWAY && __HIGHBITS) -describe HTML_CHARSET_FARAWAY A foreign language charset used in HTML markup -tflags HTML_CHARSET_FARAWAY userconf - -meta HTML_MIME_NO_HTML_TAG MIME_HTML_ONLY && !__TAG_EXISTS_HTML -describe HTML_MIME_NO_HTML_TAG HTML-only message, but there is no HTML tag - -meta HTML_MISSING_CTYPE (!__MIME_HTML && HTML_MESSAGE) -describe HTML_MISSING_CTYPE Message is HTML without HTML Content-Type - -########################################################################### -# rawbody HTML tests - -rawbody HIDE_WIN_STATUS /<[^>]{1,1000}onMouseOver=[^>]{1,1000}window\.status=/i -describe HIDE_WIN_STATUS Javascript to hide URLs in browser - -rawbody __OBFUSCATING_COMMENT_A /\w(?:]*>)+\w/ -rawbody __OBFUSCATING_COMMENT_B /[^\s>](?:]*>)+[^\s<]/ -ifplugin Mail::SpamAssassin::Plugin::HTMLEval -ifplugin Mail::SpamAssassin::Plugin::MIMEEval -meta OBFUSCATING_COMMENT ((__OBFUSCATING_COMMENT_A && HTML_MESSAGE) || (__OBFUSCATING_COMMENT_B && MIME_HTML_ONLY)) && !__ISO_2022_JP_DELIM -describe OBFUSCATING_COMMENT HTML comments which obfuscate text -endif -endif - -# spams that are assembled from a Javascript array -# look for the XOR op -rawbody __JS_FROMCHARCODE /String\.fromCharCode\s*\(\s*\S+\s*\[\s*\S+\s*\]\s*\^/ -rawbody __JS_DOCWRITE /document\.write/ -meta JS_FROMCHARCODE (__JS_FROMCHARCODE && __JS_DOCWRITE) -describe JS_FROMCHARCODE Document is built from a Javascript charcode array - -# a good possible rule that may resurface -# ! $ % ' ( ) , - . / : ; = ? @ _ -#rawbody ENTITY_DEC_OTHER /\&\#0*(?:3[3679]|4[014567]|5[89]|6[134]|95)\;/ -#describe ENTITY_DEC_OTHER HTML contains needlessly encoded punctuation - -body __HIGHBITS /(?:[\x80-\xff].?){4}/ -# note: __HIGHBITS is used by HTML_CHARSET_FARAWAY - -########################################################################### - -ifplugin Mail::SpamAssassin::Plugin::HTMLEval - -# HTML control test, HTML spam rules should all have better S/O than this -body HTML_MESSAGE eval:html_test('html') -describe HTML_MESSAGE HTML included in message - -# HTML comment tests -body HTML_COMMENT_SHORT eval:html_text_match('comment', '') -describe HTML_COMMENT_SHORT HTML comment is very short - -body HTML_COMMENT_SAVED_URL eval:html_text_match('comment', '\w/ - tflags __HTML_SHRT_CMNT_OBFU multiple maxhits=10 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __HTML_SHRT_CMNT_OBFU_MANY __HTML_SHRT_CMNT_OBFU > 5 && HTML_MESSAGE -endif - -rawbody __HTML_SINGLET />\s*(?:[a-z"]|&\#(?:\d+|x[0-9a-f]+);)\s* 10 - -meta __HTML_SINGLET_MANY __HTML_SINGLET > 20 - -ifplugin Mail::SpamAssassin::Plugin::HTMLEval - body __HTML_TAG_BALANCE_CENTER eval:html_tag_balance('center', '!= 0') -endif - -body __HUSH_HUSH /\b(?:confiden[tc]i[ae]l(?:\b|ity\b|it(?:=E9|[\xe9]|[\xc3][\xa9]))|private\b|secr[e\xe8](?:te?|cy)\b|sensitive\b|concealed\b|obscured?\b|discre(?:et|tion)\b|very\sdiscrete|top\ssecret|vertraulich(?:en)?\b|geheim\b|priv(?:e|=E9|[\xe9]|[\xc3][\xa9]))/i - -uri __IMGUR_IMG m,^https?://(?:[^.]+\.)?imgur\.com/[a-z0-9]{7}\.(?:png|gif|jpe?g)$,i -tflags __IMGUR_IMG multiple maxhits=4 - -meta __IMGUR_IMG_2 __IMGUR_IMG == 2 - -meta __IMGUR_IMG_3 __IMGUR_IMG == 3 - -if !plugin(Mail::SpamAssassin::Plugin::ImageInfo) - meta __IMG_LE_300K 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ImageInfo - body __IMG_LE_300K eval:pixel_coverage('all',62500,300000) -endif - -body __INHERIT_PMT /\binheritance\spayment\s/i - -body __INTL_BANK /\b(?:international\s(?:\w+\s)?bank|banque\sinternationale)\b/i - -body __INVEST_COUNTRY /\binvest\sin\syour?\scountry\b/i - -body __INVEST_MONEY /\binvest(?:ir)?\s(?:this|ces|d[ae]s|sur ce|de ces)\s(?:money|f[ou]nds?)\b/i - -header __IP_IN_RELAY X-Spam-Relays-External =~ /^\[ ip=(\d+)\.(\d+)\.(\d+)\.(\d+) (?:[^\]]* )?(?:rdns|helo)=\S*(?:\1\D\2\D\3\D\4|\4\D\3\D\2\D\1)/ - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __ISO_ATTACH 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __ISO_ATTACH Content-Disposition =~ m,\bfilename="?[^"]+\.iso[";$],i -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __ISO_ATTACH_MT 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __ISO_ATTACH_MT Content-Type =~ m,\bapplication/x-iso9660-image\b,i -endif - -body __IS_LEGAL /\b(?:(?:(this|esta)\s(?:deal|offer|transac[tc]i(?:o|[\xc3][\xb3])n|proposal|exchange|arrangement|work)|it)?\s[ie]s\s(?:(?:guaranteed|completely|absolutely|perfectly|100%|very|fully)\s)?(?:legal|hitch-free|seguro|legitimate)|legitimate\sarrangement|toute?\sl(?:e|=E9|[\xe9]|[\xc3][\xa9])gale)\b/i - -body __IVORY_COAST /\b(?:Cote\s?D.Ivoire|Ivory\s?Coast|Costa\sde\sMarfil)\b/i - -body __I_INHERIT /\b(?:I|eu)\s[a-z\s]{0,30}(?:inherited|herdei)\b/i - -body __I_WILL_YOU /\bwill(?:ed)?\s(?:[a-z\s]{0,20}(?:fortune|money|\$[\d,]+[a-z]{0,9})\s)?to\syou\b/i - -header __JM_REACTOR_DATE Date =~ / \+0000$/ - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __JPEG_ATTACH Content-Type =~ /image\/jpe?g/i -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __KAM_BLOCK_UTF7_2 Content-Type =~ /charset=(?:unicode-\d+-\d+-)?utf-7/i -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - body __KAM_BODY_LENGTH_LT_1024 eval:check_body_length('1024') - describe __KAM_BODY_LENGTH_LT_1024 The length of the body of the email is less than 1024 bytes. -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - body __KAM_BODY_LENGTH_LT_128 eval:check_body_length('128') - describe __KAM_BODY_LENGTH_LT_128 The length of the body of the email is less than 128 bytes. -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - body __KAM_BODY_LENGTH_LT_256 eval:check_body_length('256') - describe __KAM_BODY_LENGTH_LT_256 The length of the body of the email is less than 256 bytes. -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - body __KAM_BODY_LENGTH_LT_512 eval:check_body_length('512') - describe __KAM_BODY_LENGTH_LT_512 The length of the body of the email is less than 512 bytes. -endif -endif - -if !plugin(Mail::SpamAssassin::Plugin::HTMLEval) -meta __KAM_HTML_FONT_INVALID 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::HTMLEval -body __KAM_HTML_FONT_INVALID eval:html_test('font_invalid_color') -endif - -body __KAM_LOTTO2 /((ticket|serial|lucky) number|secret pin ?code|batch number|reference number|promotion date)/is - -header __KB_DATE_CONTAINS_TAB Date:raw =~ /^\t/ - -header __KB_MSGID_OUTLOOK_888 Message-Id =~ /^<[0-9a-f]{8}(?:\$[0-9a-f]{8}){2}\@/ - -meta __KHOP_NO_FULL_NAME !(__NOT_A_PERSON || __FROM_ENCODED_QP || __FROM_NEEDS_MIME || __FROM_FULL_NAME) - -if !(can(Mail::SpamAssassin::Conf::feature_bug6558_free)) - meta __LARGE_PERCENT_AFTER 0 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - body __LARGE_PERCENT_AFTER /\d{3}% after/i - tflags __LARGE_PERCENT_AFTER multiple maxhits=4 -endif - -if !plugin(Mail::SpamAssassin::Plugin::HeaderEval) - meta __LCL__ENV_AND_HDR_FROM_MATCH 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::HeaderEval - meta __LCL__ENV_AND_HDR_FROM_MATCH __ENV_AND_HDR_FROM_MATCH -endif - -if !plugin(Mail::SpamAssassin::Plugin::BodyEval) - meta __LCL__KAM_BODY_LENGTH_LT_1024 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval -if !(can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length)) - meta __LCL__KAM_BODY_LENGTH_LT_1024 0 -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - meta __LCL__KAM_BODY_LENGTH_LT_1024 __KAM_BODY_LENGTH_LT_1024 -endif -endif - -if !plugin(Mail::SpamAssassin::Plugin::BodyEval) - meta __LCL__KAM_BODY_LENGTH_LT_128 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval -if !(can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length)) - meta __LCL__KAM_BODY_LENGTH_LT_128 0 -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - meta __LCL__KAM_BODY_LENGTH_LT_128 __KAM_BODY_LENGTH_LT_128 -endif -endif - -if !plugin(Mail::SpamAssassin::Plugin::BodyEval) - meta __LCL__KAM_BODY_LENGTH_LT_512 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval -if !(can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length)) - meta __LCL__KAM_BODY_LENGTH_LT_512 0 -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::BodyEval - if can(Mail::SpamAssassin::Plugin::BodyEval::has_check_body_length) - meta __LCL__KAM_BODY_LENGTH_LT_512 __KAM_BODY_LENGTH_LT_512 -endif -endif - -meta __LINKED_IMG_NOT_RCVD_LINK __URI_IMG_LINKEDIN && !__HDR_RCVD_LINKEDIN - -meta __LIST_PARTIAL __DOS_HAS_LIST_UNSUB && !__DOS_HAS_LIST_ID - -meta __LIST_PRTL_PUMPDUMP __LIST_PARTIAL && __PD_CNT_1 - -meta __LIST_PRTL_SAME_USER __LIST_PARTIAL && __TO_EQ_FROM_USR - -body __LITECOIN_ID /\b(?[^<\s]{1400}/i - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __LONG_STY_INVIS __STY_INVIS && __LONGLINE -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __LOTSA_MONEY_00 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __LOTSA_MONEY_00 /[\s\.]?[\dOo][,\.][\dOo]{3}(?:(?!\d)|\b)/ -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __LOTSA_MONEY_01 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __LOTSA_MONEY_01 /(?:(?i:sum\sof\s)[\(\[]?|\s?)[\s\.]?[\d.,\sOo]{5,20}[\dOo](?[\d.,\sOo]{5,20}[\dOo][\)\]\(]?\s?(?:|Pounds|(?i:dollars?|bucks))\b/ -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __LOTSA_MONEY_03 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __LOTSA_MONEY_03 /(?:(?i:sum\sof\s)[\(\[]?|\s?)[\d.,\sOo]{0,5}[\)\]]?\s?(?i:M(?i:il+)?\b|mil+(?i:io|)n|hund?[re]+a?[dt]|thousand|tausend|milh[\xf5]es)/ -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __LOTSA_MONEY_04 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __LOTSA_MONEY_04 /(?:(?[\d\.,]{0,4}(?:M|\smilli?one?s|\s?mln)|million(?!s)|milln|hund?rea?d(?!s)[^\.]{1,25}thousand(?!s)|cents?[^\.]{1,25}mille|hundert[^\.]{1,30}tausend|ientos?[^\.]{1,20}mil|cent[a-z\s]{1,20}mil\s[a-z]{1,20}centos)[^\.\$]{0,50}?(?:(?:U\.?\s?S\.?\s?(?:A\.?\s?)?|united\s?states\s|E\.\s?U\.\s|canad(?:ian|a)\s|(?:ia\s)?de\s)?d(?:[o\xf3]|[\xc3][\xb3])l+are?s?|\bbucks|USD|GBP|\spounds?|(?:\s)?pounds?\ssterling|pounds(?!\sof)|(?:d'\s?)?euros?|francs?)\b/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __LOTSA_MONEY_05 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __LOTSA_MONEY_05 /(?:(?:sum|value|amount)\sof\s)[\d.,\sO]{7,20}[\dO\.][\)\]\(\s]{0,3}(?:pounds?|dollars?|euros?|bucks)\b/i -endif - -meta __LOTTO_ADMITS __LOTTO_ADMITS_1 || __LOTTO_ADMITS_2 || __LOTTO_ADMITS_3 || __LOTTO_ATTACH_1 || __LOTTO_ATTACH_2 - -body __LOTTO_ADMITS_1 /\b(?:on-?line|e-?mail|ballot|(?:inter)?national|state|(?:UK|euro)[- ]?(?:mil+ions?|PW)|Canada|Microsoft|MSN|internet|mega|jackpot+|Royal Heritage|foundation|cash\sgrant|mercato|univers|staatsloterij|bill\s?gates|Olympics?|swiss|this|est[ea]|internationaux de gagnants de)(?:\s(?!lot|swe|prom)\w{1,20}){0,3}\s?(?:lot(?:to|t+ery|eri[ea])|sweepstakes?|promo(?:tion|cao|cion)?|jackpot+)\b/i - -body __LOTTO_ADMITS_2 /\b(?:free)?(?:lot(?:to|tery|erie)|sweepstakes)\s(?:(?:inter)?na[tz]ional|department|bureau|group|award|microsoft)/i - -uri __LOTTO_ADMITS_3 /lott+ery/i - -meta __LOTTO_AGENT __LOTTO_AGENT_01 || __LOTTO_AGENT_02 - -body __LOTTO_AGENT_01 /\b(?:(?:(?:the|y?our)(?:\s\w{1,20})?|contact|accredited|listed)\sclaim(?:s|ing)?(?:\sprocessing)?|fiducia\w+|reimbursement|(?:prize|international|intl|foreign|win+ing)(?:[\s,.]+(?:rem+it+ance|settlement|payment|payout|award|transfer))+|payment|payout|immunity|(? 1 - -meta __MANY_SPAN_IN_TEXT (__SPAN_BEG_TEXT > 4) && (__SPAN_END_TEXT > 4) - -header __MAY_BE_FORGED Received =~ /\(may be forged\)/ - -header __MID_START_001C Message-ID =~ /^<000001c/ - -body __MILLIONS /\bmillions\sof\s(?:dollar|euro|pound)/i - -header __MIMEOLE_1106 X-MimeOLE =~ /^Produced By Microsoft MimeOLE V6.00.2800.1106$/ - -meta __MIMEOLE_DIRECT_TO_MX __HAS_MIMEOLE && __DOS_DIRECT_TO_MX - -header __MIME_BDRY_0D0D Content-Type =~ /boundary="-{12}(?:0[1-9]){12}/ - -if !((version >= 3.004000)) - meta __MIME_CTYPE_IN_BODY 0 -endif - -if (version >= 3.004000) - body __MIME_CTYPE_IN_BODY /^Content-Type:\s/ -endif - -if !((version >= 3.004000)) - meta __MIME_MALF 0 -endif - -if (version >= 3.004000) - meta __MIME_MALF __CTYPE_MULTIPART_ANY && __MIME_CTYPE_IN_BODY -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __MIME_NO_TEXT 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - meta __MIME_NO_TEXT (__CTYPE_MULTIPART_ANY && !__ANY_TEXT_ATTACH) -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - rawbody __MIME_QPC eval:check_for_mime('mime_qp_count') -endif - -header __MISSING_REF References =~ /^UNSET$/ [if-unset: UNSET] - -header __MISSING_REPLY In-Reply-To =~ /^UNSET$/ [if-unset: UNSET] - -rawbody __MIXED_AREA_CASE /<(?!AREA|area)[Aa][Rr][Ee][Aa]\s/ - -rawbody __MIXED_CENTER_CASE /<(?!CENTER|center)[Cc][Ee][Nn][Tt][Ee][Rr]>/ - -rawbody __MIXED_FONT_CASE /<(?!FONT|font)[Ff][Oo][Nn][Tt]\s/ - -rawbody __MIXED_HREF_CASE_JH /<[Aa](?i:rea)?\s+(?!HREF|href)[Hh][Rr][Ee][Ff]=/ - -rawbody __MIXED_IMG_CASE_JH /<(?!IMG|img)[Ii][Mm][Gg]\s/ - -header __MOLE_2962 X-MimeOLE =~ /^Produced\ By\ Microsoft\ MimeOLE\ V6\.00\.2900\.2962$/ - -meta __MONERO (__MONERO_ID || __MONERO_CURNCY || __URI_MONERO || __FUZZY_MONERO) - -body __MONERO_CURNCY /Monero \(XMR\)/ - -body __MONERO_ID /\b4[0-9AB][1-9A-HJ-NP-Za-km-z]{93,104}\b/ - -meta __MONEY_ATM_CARD LOTS_OF_MONEY && __ATM_CARD - -meta __MONEY_FORM LOTS_OF_MONEY && __FILL_THIS_FORM - -meta __MONEY_FORM_SHORT LOTS_OF_MONEY && __FILL_THIS_FORM_SHORT - -meta __MONEY_FRAUD_3 LOTS_OF_MONEY && (__FRAUD_VQE + __FRAUD_KJV + __FRAUD_IRJ + __FRAUD_NEB + __FRAUD_XJR + __FRAUD_DPR + __FRAUD_BEP + __FRAUD_TDP + __FRAUD_GAN + __FRAUD_IRT + __FRAUD_AON + __FRAUD_WNY + __FRAUD_IPK + __FRAUD_QXX + __FRAUD_IOV + __FRAUD_MLY + __FRAUD_ULK + __FRAUD_BGP + __FRAUD_YWW + __FRAUD_JYG + __FRAUD_XWW + __FRAUD_UUY + __FRAUD_SNT + __FRAUD_JNB + __FRAUD_QFY + __FRAUD_WDR + __FRAUD_WFC + __FRAUD_AUM + __FRAUD_MCQ + __FRAUD_PVN + __FRAUD_FVU + __FRAUD_CKF + __FRAUD_MQO + __FRAUD_TCC + __FRAUD_GBW + __FRAUD_AXF + __FRAUD_THJ + __FRAUD_YQV + __FRAUD_YJA + __FRAUD_YPO + __FRAUD_UOQ + __AFRICAN_STATE + __AGREED_RATIO + __AM_DYING + __ATM_CARD + __BACK_SCRATCH + __BARRISTER + __BENEFICIARY + __COMPENSATION + __CONTACT_ATTY + __CONTACT_YOU + __COURIER + __DEAD_PARENT + __DEAL + DEAR_BENEFICIARY + DEAR_WINNER + __DECEASED + __DESTROY_ME + __DIED_IN + __DIPLOMATIC + __DORMANT_ACCT + __EARLY_DEMISE + EMRCP + __EX_CUSTOMER + __FEES + __FIFTY_FIFTY + __FOUND_YOU + __FRAUD + __FRAUD_PTX + __HUSH_HUSH + __I_INHERIT + __INHERIT_PMT + __INTL_BANK + __INVEST_COUNTRY + __INVEST_MONEY + __IS_LEGAL + __I_WILL_YOU + __KAM_LOTTO2 + __LOTTO_ADMITS + LOTTO_AGENT + __LOTTO_DEPT + __LOTTO_RELATED + __LOTTO_VERIFY + T_LOTTO_URI + __LOTTO_WIN_01 + __LOTTO_WINNINGS + __LUCKY_WINNER + __LUCRATIVE + __MILLIONS + __MY_FORTUNE + __NEXT_OF_KIN + __NOT_DEAD_YET + __NOT_SCAM + __OUR_BEHALF + __SCAM + __SHARE_IT + __SUM_OF_FUND + __SURVIVORS + __THEY_INHERIT + __TRTMT_DEFILED + __TRUNK_BOX + __UN + UNCLAIMED_MONEY + __WIDOW + __WILL_LEGAL + __XFER_MONEY + __YOU_ASSIST + __YOU_INHERIT + __YOUR_BANK + __YOUR_FUND + __YOUR_PERM + __YOUR_PROFIT + __YOU_WON + T_LOTTO_AGENT_FM + T_LOTTO_AGENT_RPLY + __PCT_FOR_YOU + __PCT_OF_PMTS + __RANDOM_PICK + __CHARITY > 3) - -meta __MONEY_FRAUD_5 LOTS_OF_MONEY && (__FRAUD_VQE + __FRAUD_KJV + __FRAUD_IRJ + __FRAUD_NEB + __FRAUD_XJR + __FRAUD_DPR + __FRAUD_BEP + __FRAUD_TDP + __FRAUD_GAN + __FRAUD_IRT + __FRAUD_AON + __FRAUD_WNY + __FRAUD_IPK + __FRAUD_QXX + __FRAUD_IOV + __FRAUD_MLY + __FRAUD_ULK + __FRAUD_BGP + __FRAUD_YWW + __FRAUD_JYG + __FRAUD_XWW + __FRAUD_UUY + __FRAUD_SNT + __FRAUD_JNB + __FRAUD_QFY + __FRAUD_WDR + __FRAUD_WFC + __FRAUD_AUM + __FRAUD_MCQ + __FRAUD_PVN + __FRAUD_FVU + __FRAUD_CKF + __FRAUD_MQO + __FRAUD_TCC + __FRAUD_GBW + __FRAUD_AXF + __FRAUD_THJ + __FRAUD_YQV + __FRAUD_YJA + __FRAUD_YPO + __FRAUD_UOQ + __AFRICAN_STATE + __AGREED_RATIO + __AM_DYING + __ATM_CARD + __BACK_SCRATCH + __BARRISTER + __BENEFICIARY + __COMPENSATION + __CONTACT_ATTY + __CONTACT_YOU + __COURIER + __DEAD_PARENT + __DEAL + DEAR_BENEFICIARY + DEAR_WINNER + __DECEASED + __DESTROY_ME + __DIED_IN + __DIPLOMATIC + __DORMANT_ACCT + __EARLY_DEMISE + EMRCP + __EX_CUSTOMER + __FEES + __FIFTY_FIFTY + __FOUND_YOU + __FRAUD + __FRAUD_PTX + __HUSH_HUSH + __I_INHERIT + __INHERIT_PMT + __INTL_BANK + __INVEST_COUNTRY + __INVEST_MONEY + __IS_LEGAL + __I_WILL_YOU + __KAM_LOTTO2 + __LOTTO_ADMITS + LOTTO_AGENT + __LOTTO_DEPT + __LOTTO_RELATED + __LOTTO_VERIFY + T_LOTTO_URI + __LOTTO_WIN_01 + __LOTTO_WINNINGS + __LUCKY_WINNER + __LUCRATIVE + __MILLIONS + __MY_FORTUNE + __NEXT_OF_KIN + __NOT_DEAD_YET + __NOT_SCAM + __OUR_BEHALF + __SCAM + __SHARE_IT + __SUM_OF_FUND + __SURVIVORS + __THEY_INHERIT + __TRTMT_DEFILED + __TRUNK_BOX + __UN + UNCLAIMED_MONEY + __WIDOW + __WILL_LEGAL + __XFER_MONEY + __YOU_ASSIST + __YOU_INHERIT + __YOUR_BANK + __YOUR_FUND + __YOUR_PERM + __YOUR_PROFIT + __YOU_WON + T_LOTTO_AGENT_FM + T_LOTTO_AGENT_RPLY + __PCT_FOR_YOU + __PCT_OF_PMTS + __RANDOM_PICK + __CHARITY > 5) - -meta __MONEY_FRAUD_8 LOTS_OF_MONEY && (__FRAUD_VQE + __FRAUD_KJV + __FRAUD_IRJ + __FRAUD_NEB + __FRAUD_XJR + __FRAUD_DPR + __FRAUD_BEP + __FRAUD_TDP + __FRAUD_GAN + __FRAUD_IRT + __FRAUD_AON + __FRAUD_WNY + __FRAUD_IPK + __FRAUD_QXX + __FRAUD_IOV + __FRAUD_MLY + __FRAUD_ULK + __FRAUD_BGP + __FRAUD_YWW + __FRAUD_JYG + __FRAUD_XWW + __FRAUD_UUY + __FRAUD_SNT + __FRAUD_JNB + __FRAUD_QFY + __FRAUD_WDR + __FRAUD_WFC + __FRAUD_AUM + __FRAUD_MCQ + __FRAUD_PVN + __FRAUD_FVU + __FRAUD_CKF + __FRAUD_MQO + __FRAUD_TCC + __FRAUD_GBW + __FRAUD_AXF + __FRAUD_THJ + __FRAUD_YQV + __FRAUD_YJA + __FRAUD_YPO + __FRAUD_UOQ + __AFRICAN_STATE + __AGREED_RATIO + __AM_DYING + __ATM_CARD + __BACK_SCRATCH + __BARRISTER + __BENEFICIARY + __COMPENSATION + __CONTACT_ATTY + __CONTACT_YOU + __COURIER + __DEAD_PARENT + __DEAL + DEAR_BENEFICIARY + DEAR_WINNER + __DECEASED + __DESTROY_ME + __DIED_IN + __DIPLOMATIC + __DORMANT_ACCT + __EARLY_DEMISE + EMRCP + __EX_CUSTOMER + __FEES + __FIFTY_FIFTY + __FOUND_YOU + __FRAUD + __FRAUD_PTX + __HUSH_HUSH + __I_INHERIT + __INHERIT_PMT + __INTL_BANK + __INVEST_COUNTRY + __INVEST_MONEY + __IS_LEGAL + __I_WILL_YOU + __KAM_LOTTO2 + __LOTTO_ADMITS + LOTTO_AGENT + __LOTTO_DEPT + __LOTTO_RELATED + __LOTTO_VERIFY + T_LOTTO_URI + __LOTTO_WIN_01 + __LOTTO_WINNINGS + __LUCKY_WINNER + __LUCRATIVE + __MILLIONS + __MY_FORTUNE + __NEXT_OF_KIN + __NOT_DEAD_YET + __NOT_SCAM + __OUR_BEHALF + __SCAM + __SHARE_IT + __SUM_OF_FUND + __SURVIVORS + __THEY_INHERIT + __TRTMT_DEFILED + __TRUNK_BOX + __UN + UNCLAIMED_MONEY + __WIDOW + __WILL_LEGAL + __XFER_MONEY + __YOU_ASSIST + __YOU_INHERIT + __YOUR_BANK + __YOUR_FUND + __YOUR_PERM + __YOUR_PROFIT + __YOU_WON + T_LOTTO_AGENT_FM + T_LOTTO_AGENT_RPLY + __PCT_FOR_YOU + __PCT_OF_PMTS + __RANDOM_PICK + __CHARITY > 8) - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - meta __MONEY_FREEMAIL_REPTO LOTS_OF_MONEY && __freemail_hdr_replyto -endif - -meta __MONEY_FROM_41 __NSL_RCVD_FROM_41 && LOTS_OF_MONEY - -body __MOVE_MONEY /\b(?:(?:receive|re-?profile|transfer(?:ring|ir|t)?|release|repatriat(?:e|ion)|rapatrier|secure|r(?:e|=E9|[\xe9]|[\xc3][\xa9])clamation|possession|virer|dona(?:te|r)|depositante|dep[\xc3][\xb3]sito)\s(?:th(?:e(?:se)?|is)|d[ae]s|sur ce|de ce[st]|cet|est[eao]s?|del?)|re-?profiling|receive|re-?locat(?:e|ing)(?:\s\w{1,15})?)\s(?:of\s|your\s|the\s){0,2}(?:sums?\sof\s|inheritance\s)?(?:proceeds|funds?|money|balance|account|g[eo]ld|compte|fond[so]{1,2}|dinero|argent)\b/i - -meta __MSGID_DOLLARS_URI_IMG __MSGID_DOLLARS_MAYBE && __HAS_ANY_URI && __HTML_LINK_IMAGE - -header __MSGID_GUID Message-ID =~ /^/m - -meta __MSMAIL_PRI_ABNORMAL __HAS_MSMAIL_PRI && !__MSMAIL_PRI_NORMAL - -header __MSMAIL_PRI_HIGH X-MSMail-Priority =~ /^(?:high|urgent)$/i - -header __MSMAIL_PRI_NORMAL X-MSMail-Priority =~ /^normal$/i - -meta __MSM_PRIO_REPTO __HAS_MSMAIL_PRI && __HAS_REPLY_TO && __SUBJ_SHORT - -header __MSOE_MID_WRONG_CASE ALL =~ /\nMessage-Id: / - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __MSO_THEME_MT Content-Type =~ m,\bapplication/vnd.ms-officetheme\b,i -endif - -header __MTLANDROID_MUA X-Mailer =~ /\bMotorola android mail \d+\.\d/ - -header __MUA_TBIRD User-Agent =~ /^Mozilla\/(.*) Thunderbird/ - -body __MY_FORTUNE /\b(?:my|his|her)\s(?:fortune|heritage)\b/i - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __MY_MALWARE /\b(?:(?:I(?:'ve|\shave)?\s(?:put|set\s?up|installed|buil[td]\sin|placed)\s(?:a\s)?|my\s(?:personal\s|background\s|hidden\s)?)(?:mal+ware|virus|spy\s?ware|trojan|program\srecorded|expl[o0]it|backdoor|(?:sneaky\s|hidden\s|malicious\s)+(?:app|stuff))|(?:application|mal+ware)[^\.]{1,30}(?:enable[sd]|allow(?:s|ed))\sme\sto\s(?:access|control)|I\s(?:contaminated|infected|hacked|toxified|poisoned)\s(?:your|this)\s(?:machine|computer|gadget|(?:smart\s?)?phone|device|email)|Anwendung\s[^\.]{1,50}\sich\sauf\salle\sIhre\sdarauf\sgespeicherten\sDateien\szugreifen\skann|mein\shinterhältiges\sProgramm|I\s?am\s?a\s?hacker|(?:(?:trojan|virus|spyware|mal+ware)\s)+giv(?:es|ing)\sme)\b/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __MY_MALWARE /(?:^|\s)(?:(?:(?:'|\s)?\s(?:

<|>\s?

||(?:|)\s|

)\s(?:\s)?|\s(?:

\s|\s|\s)?)(?:+||

\s?||

\s|

(?:|0)||(?:\s|\s|\s)+(?:

|))|(?:

|+)[^\.]{1,30}(?:(?:|)|(?:|))\s\s\s(?:|)|\s(?:||||

)\s(?:|)\s(?:|

||(?:\s?)?

||)|Anwendung\s[^\.]{1,50}\sich\sauf\salle\sIhre\sdarauf\sgespeicherten\sDateien\szugreifen\skann|\s\s

+|\s?\s?\s?|(?:(?:||

|+)\s)+(?:|)\s)[\s\.,]/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __MY_VICTIM /\b(?:hi|hello),?(?:\smy)?\s(?:victim|prey)\b/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __MY_VICTIM /(?:|),?(?:\s)?\s(?:|

)/i -endif - -header __NAKED_TO To =~ /^[^\s<>]+\@[^\s<>]+$/ - -meta __NAME_EMAIL_DIFF __NAME_IS_EMAIL && ! __NAME_EQ_EMAIL - -header __NAME_EQ_EMAIL From:raw =~ /([\w+.-]+\@[\w.-]+\.\w\w+)["'`\s]*<\s*\1>/i - -header __NAME_IS_EMAIL From:raw =~ /\w\@[\w.-]+\.\w\w+["'`]*\s*<\w+\@\w/ - -body __NEVER_HEAR_EN /(never hear me again|destroy all your secrets|not bother you again|leave you alone)/i - -body __NEVER_HEAR_IT /eliminare tutti i tuoi segreti|Ti garantisco che non ti disturbe/i - -meta __NEWEGG_IMG_NOT_RCVD_NEGG __URI_IMG_NEWEGG && !__HDR_RCVD_NEWEGG - -body __NEW_PRODUCTS /\bhere are new products|\b(?:Our company|we) (?:has |have )?(?:(?:recently|just|newly) (?:introduce|release|launche)[ds](?: a| our| the)? (?:new|(?:\w+\s){1,5}below)|a new (?!cat\s|kitten\s|dog\s|puppy\s|pet\s|baby\s|child\s|boy\s|girl\s)(?:\w+\s){1,5} here)|recently,? our company (?:launch|releas)ed|\bI want to recommend a new (?:\w+ ){1,5}(?:we|our)\b|latest version of our (?:stock|product)|\b(?:our|a) new (?:\w+ ){1,3}has (?:recently|just) been released/i - -body __NEXT_OF_KIN /\bnext[-\s]of[-\s]kin\b/i - -body __NIGERIA /\bnigeria\b/i - -meta __NORDNS_LOW_CONTRAST HTML_FONT_LOW_CONTRAST && __RDNS_NONE - -meta __NOT_A_PERSON __VACATION || ANY_BOUNCE_MESSAGE || __CHALLENGE_RESPONSE || __VIA_ML || __DOS_HAS_LIST_UNSUB || __SENDER_BOT || __UNSUB_LINK || __UNSUB_EMAIL || __MSGID_LIST || __SUBSCRIPTION_INFO -tflags __NOT_A_PERSON nice - -body __NOT_DEAD_YET /\b(?:will\sinherit|que\sherede|your\sdeath|your?\sbeing\sdead)\b/i - -body __NOT_SCAM /\b(?:not\sa\sscam|(?:not|never)\sscam\syou)\b/i - -tflags __NOT_SPOOFED nice - -if !(!plugin(Mail::SpamAssassin::Plugin::DKIM)) -if !plugin(Mail::SpamAssassin::Plugin::SPF) - meta __NOT_SPOOFED DKIM_VALID || !__LAST_EXTERNAL_RELAY_NO_AUTH || ALL_TRUSTED # yes DKIM, no SPF -endif -endif - -if !(!plugin(Mail::SpamAssassin::Plugin::DKIM)) - ifplugin Mail::SpamAssassin::Plugin::SPF - meta __NOT_SPOOFED SPF_PASS || DKIM_VALID || !__LAST_EXTERNAL_RELAY_NO_AUTH || ALL_TRUSTED # yes DKIM, yes SPF -endif -endif - -if !plugin(Mail::SpamAssassin::Plugin::DKIM) -if !plugin(Mail::SpamAssassin::Plugin::SPF) - meta __NOT_SPOOFED __DKIM_EXISTS || !__LAST_EXTERNAL_RELAY_NO_AUTH || ALL_TRUSTED # no DKIM, no SPF. -endif -endif - -if !plugin(Mail::SpamAssassin::Plugin::DKIM) - ifplugin Mail::SpamAssassin::Plugin::SPF - meta __NOT_SPOOFED SPF_PASS || __DKIM_EXISTS || !__LAST_EXTERNAL_RELAY_NO_AUTH || ALL_TRUSTED # no DKIM, yes SPF -endif -endif - -meta __NO_INR_YES_REF (__XM_GNUS || __XM_MSOE5 || __XM_MSOE6 || __XM_MOZ4 || __XM_SKYRI || __XM_WWWMAIL || __UA_GNUS || __UA_KNODE || __UA_MUTT || __UA_PAN || __UA_XNEWS) - -header __NSL_ORIG_FROM_41 X-Originating-IP =~ /^(?:.+\[)?41\./ -describe __NSL_ORIG_FROM_41 Originates from 41.0.0.0/8 - -header __NSL_RCVD_FROM_41 X-Spam-Relays-External =~ / ip=41\./ -describe __NSL_RCVD_FROM_41 Received from 41.0.0.0/8 - -header __NUMBERONLY_TLD From:addr =~ /\@[0-9]{4,}(\.[a-z]{2,4})?\.[a-z]+$/i - -header __NUMBERS_IN_SUBJ Subject =~ /\d{3}/ - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __OBFU_BITCOIN ( __BITCOIN_ID && ( __BTC_OBFU_2 || __BTC_OBFU_3 || __BTC_OBFU_4 || __BTC_OBFU_5 ) ) -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - meta __OBFU_BITCOIN ( __BITCOIN_ID && ( __BTC_OBFU_2 || __BTC_OBFU_3 || FUZZY_BITCOIN || __BTC_OBFU_5 ) ) -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __OBFU_BITCOIN_NOID ( !__BITCOIN_ID && ( __BTC_OBFU_2 || __BTC_OBFU_3 || __BTC_OBFU_4 || __BTC_OBFU_5 ) ) -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - meta __OBFU_BITCOIN_NOID ( !__BITCOIN_ID && ( __BTC_OBFU_2 || __BTC_OBFU_3 || FUZZY_BITCOIN || __BTC_OBFU_5 ) ) -endif - -body __OBFU_UNSUB_UL /(?:click_here|remove_your|our_e?mail|this_list|to_unsubscribe|future_e?mail|our_list)/ - -if !plugin(Mail::SpamAssassin::Plugin::ImageInfo) - meta __ONE_IMG 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ImageInfo - body __ONE_IMG eval:image_count('all',1,1) -endif - -header __OPERA_MID_NON_OP Message-ID =~ /^<[^o][^p]\./ - -body __OUR_BEHALF /\b(?:on\s(?:my|our)\sbehalf|of\sbehalf\sof)\b/i - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __PART_CID_STOCK_LESS Content-ID =~ /^<00[a-f0-9]{10}\$[a-f0-9]{8}\$[a-f0-9]{8}\@[A-Za-z]+>$/ -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __PART_STOCK_CD_F Content-Disposition =~ /filename/ -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __PART_STOCK_CID Content-ID =~ /^<[a-f0-9]{12}\$[a-f0-9]{8}\$[a-f0-9]{8}\@[^\s\.]+>$/ -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __PART_STOCK_CL Content-Location =~ /./ -endif - -body __PASSIVE_INCOME /\bpassive income\b/i - -body __PASSWORD /\bp[-\s_]?a[-\s_]?s[-\s_]?s[-\s_]?w[-\s_]?o[-\s_]?r[-\s_]?d\b/i - -body __PASSWORD_EXP_CLUMSY /\bpassword is due for expiration yesterday\b/i - -body __PASSWORD_UPGRADE /\bpassword upgrade\b/i - -body __PAXFUL /\bp-?a+-?x+-?f-?u+-?l\b/i - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __PAY_ME /\b(?:pay\sme|(?:(?:send|transmit|give)\s(?:to\s)?me|(?:send(?:en\ssie)?|transfer)\s(?:the\samount\sof|exactly|genau)|I\swant|den\sbetrag\svon|payment\sof)\s(?:[\d,'.\$£]+\s?(?:usd?|eur?(?:os)?|gbp|BTC)?|bitcoin|BTC)|(?:make|perform|send|transmit)\sthe\spayment|amount\sfor\smy\ssilence|(?:pay|fund)\sthis\s(?:bitcoin|monero)[-\s](?:address|wallet|brieftasche)|my bribe(?:ry)?)\b/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __PAY_ME /(?:^|\s)(?:

\s|(?:(?:||)\s(?:\s)?|(?:(?:\s)?|)\s(?:\s\s||)|\s|\s\s|

\s)\s(?:[\d,'.\$£]+\s?(?:?|?(?:)?|

|)?||)|(?:|

||)\s\s

|\s\s\s|(?:

|)\s\s(?:|)[-\s](?:||| (?:)?))[\s\.,]/i -endif - -body __PAY_YOU /\bpay\syou\b/ - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __PCT_FOR_YOU 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - meta __PCT_FOR_YOU __PCT_FOR_YOU_1 || __PCT_FOR_YOU_2 || __PCT_FOR_YOU_3 || T_SHARE_50_50 -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __PCT_FOR_YOU_1 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __PCT_FOR_YOU_1 /[\s)]{0,3}(?:(?:of\s[\w\s]{0,35}?)?(?:for|to|as)\syour?|(?:[^\s.]{1,15}\s)?an uns beide)/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __PCT_FOR_YOU_2 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __PCT_FOR_YOU_2 /\b(?:(?:give|offer)\syou|vous\s(?:aurez\sdroit\s(?:=E0|[\xe0])|donnerai|all(?:e|=E9|[\xe9]|[\xc3][\xa9])\srecevoir\sautour\sde)|ihnen)\s/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __PCT_FOR_YOU_3 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __PCT_FOR_YOU_3 /\byour?\s(?!can)(?:(?!you)\w{1,15}\s){0,10}(?:(?:share|entiti?le(?:d|ment)?|percentage|fee|assist(?:ance)?|comp[ea]nsat(?:ed?|tion)|reward(?:ed)?|renumerat(?:e|tion)|com+is+ion|paid|deduct|account|tage|(?:will|shall|would|(?:are|stand|going)\sto)\s(?:be\s)?(?:tak(?:e|ing)|earn|get(?:ting)?|remit|subtract|with+old)|(?:deduct|taken?|subtract(?:ed)?)\syour|keep(?:ing)?|receiv(?:e|ing)|retain(?:ing)?|have|half|giv(?:en|ing)|paid|(?:give|pay|offer)\s(?:me|you|him)|bank\saccount|to\s(?:take|use)|(?:time|country)\sand|ratio\sof)(?:\s(?!you)\w{1,15}){0,10})\s(?/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - meta __PCT_OF_PMTS 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __PCT_OF_PMTS /[\s)]+(?:of\s[\w\s]{0,35}?)?(?:of|du|de)\s(?:(?:the|la)\s)?(?:total\s)?(?:payments?|rem+it+ances?|capital|chec(?:k|que)s?|mon(?:ey|ies)|suma?)/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __PDF_ATTACH 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - meta __PDF_ATTACH (__PDF_ATTACH_MT || __PDF_ATTACH_FN1 || __PDF_ATTACH_FN2) -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __PDF_ATTACH_FN1 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __PDF_ATTACH_FN1 Content-Type =~ /="[^"]+\.pdf"/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __PDF_ATTACH_FN2 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __PDF_ATTACH_FN2 Content-Disposition =~ /="[^"]+\.pdf"/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __PDF_ATTACH_MT 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __PDF_ATTACH_MT Content-Type =~ m,\bapplication/pdf\b,i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - header __PDS_BTC_ANON From:name =~ /\bAnon/ -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - meta __PDS_BTC_BADFROM ( __PDS_BTC_HACKER || __PDS_BTC_PIRATE ) -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - header __PDS_BTC_HACKER From:name =~ /hckr/i -endif - -meta __PDS_BTC_ID ( __BITCOIN_ID && !__URL_BTC_ID && !__HAS_IMG_SRC_DATA && !__BUGGED_IMG) - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - header __PDS_BTC_PIRATE From:name =~ /prt/i -endif - -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -if (version >= 3.004000) -header __PDS_CASHSHORTENER eval:check_uri_host_listed('PDS_CASHSHORTENER') -endif -endif - -uri __PDS_DOUBLE_URL m;https?://[\S]+(?:\?|=)https?://[\S]+[\w]+$; - -if (version >= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -body __PDS_EXPIRATION_NOTICE /\bexpiration (notice|alert|date)\b/i -endif -endif - -if can(Mail::SpamAssassin::Conf::perl_min_version_5010000) - header __PDS_FROM_2_EMAILS From =~ /(?:^|<|"| )([\w+.-]+\@[\w.-]+\.\w\w++)(?:[^\n\w<]{0,80})?<(?!\1)[^\n\s]*\@/i -endif - -header __PDS_FROM_GMAIL From:addr =~ /\@g(?:oogle)?mail\.com$/i - -header __PDS_FROM_NAME_TO_DOMAIN ALL =~ /From: ["']?([a-z0-9\.-]+\.[0-9a-z\.-]+)["']? [^\n]+\nTo:[^\n]+\@\1/ism - -header __PDS_GMAIL_MID Message-Id =~ /\@mail.gmail.com>$/ - -meta __PDS_GOOGLE_DRIVE_SHARE (__PDS_GOOGLE_DRIVE_SHARE_1 + __PDS_GOOGLE_DRIVE_SHARE_2 + __PDS_GOOGLE_DRIVE_SHARE_3 >= 2) - -header __PDS_GOOGLE_DRIVE_SHARE_1 References =~ /\@docs\-share\.google\.com\>/ - -header __PDS_GOOGLE_DRIVE_SHARE_2 From:addr =~ /^drive\-shares\-noreply\@google\.com$/ - -header __PDS_GOOGLE_DRIVE_SHARE_3 X-Envelope-From:addr =~ /\@doclist\.bounces\.google\.com$/ - -ifplugin Mail::SpamAssassin::Plugin::AskDNS -meta __PDS_HP_HELO_NODNS (__HELO_HIGHPROFILE && !__HELO_DNS) -tflags __PDS_HP_HELO_NODNS net -endif - -ifplugin Mail::SpamAssassin::Plugin::HTMLEval -meta __PDS_HTML_LENGTH_1024 __HTML_LENGTH_0000_1024 -endif - -ifplugin Mail::SpamAssassin::Plugin::HTMLEval -meta __PDS_HTML_LENGTH_2048 __HTML_LENGTH_0000_1024 || __HTML_LENGTH_1024_1536 || __HTML_LENGTH_1536_2048 -endif - -meta __PDS_LITECOIN_ID (__LITECOIN_ID && !__URL_LTC_ID && !__HAS_IMG_SRC_DATA && !__BUGGED_IMG) - -meta __PDS_MSG_1024 (__KAM_BODY_LENGTH_LT_1024 || __PDS_HTML_LENGTH_1024) - -meta __PDS_MSG_512 (__KAM_BODY_LENGTH_LT_512 || __HTML_LENGTH_512) - -if (version >= 3.004001) -ifplugin Mail::SpamAssassin::Plugin::AskDNS -meta __PDS_NEWDOMAIN (__FROM_FMBLA_NEWDOM || __FROM_FMBLA_NEWDOM14 || __FROM_FMBLA_NEWDOM28) -tflags __PDS_NEWDOMAIN net -endif -endif - -if (version >= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -body __PDS_OFFER_ONLY_AMERICA /This offer (?:is )?(?:only )?for (United States|USA)/i -endif -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEEval) - meta __PDS_QP_1024 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - meta __PDS_QP_1024 (__MIME_QPC > 0) && (__MIME_QPC < 1024) -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEEval) - meta __PDS_QP_128 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - meta __PDS_QP_128 (__MIME_QPC > 0) && (__MIME_QPC < 128) -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEEval) - meta __PDS_QP_512 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - meta __PDS_QP_512 (__MIME_QPC > 0) && (__MIME_QPC < 512) -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEEval) - meta __PDS_QP_64 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEEval - meta __PDS_QP_64 (__MIME_QPC > 0) && (__MIME_QPC < 64) -endif - -header __PDS_RDNS_MTA X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*(mta|mail|mx|smtp)\b\S* /i - -if (version >= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -body __PDS_SENT_TO_EMAIL_ADDR /This message was sent to Email Address\./i -endif -endif - -if (version >= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -body __PDS_SEO1 /(?:top|first page|1st) (?:(?:results|rank(?:ing)?) )?(?:in|of|on) (?:Google|MSN|Yahoo|Bing)|rank number one|top page rank|guarantee you 1st|link.building/i -endif -endif - -if (version >= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -body __PDS_SEO2 /losing your (?:[a-z]+ )?(?:rank(?:ing)?|results)|rank well on [a-z]+\b/i -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -if (version >= 3.004000) -meta __PDS_SHORT_URL __SHORT_URL && !__URL_SHORTENER && !ALL_TRUSTED -endif -endif - -if (version >= 3.004001) -ifplugin Mail::SpamAssassin::Plugin::AskDNS -tflags __PDS_SPF_ONLYALL net -endif -endif - -meta __PDS_SPOOF_GMAIL_MID __PDS_FROM_GMAIL && !__PDS_GMAIL_MID && !__FSL_RELAY_GOOGLE - -header __PDS_TONAME_EQ_TOLOCAL To:raw =~ /^\s*['"]?([^'"]+)['"]? ]+)>?\n(?:[^\n]{1,100}\n)*From:\W+(\1)([^\n\w<]++<)?((?!\1)[^\n">]++)>?\n/ism -endif - -if can(Mail::SpamAssassin::Conf::perl_min_version_5010000) - header __PDS_TO_EQ_FROM_NAME_2 ALL =~ /\nFrom:\W+"([\w+.-]+\@[\w.-]+\.\w\w+)(?:[^\n\w<]{0,80}<)?((?!\1)[^\n">]++)>?\n(?:[^\n]{1,100}\n)*To:\s+(?:[^\n<]{0,80}<)?(\1)>?/ism -endif - -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -if (version >= 3.004000) -meta __PDS_TO_SUBJ_URISHRT __TO_IN_SUBJ && __URL_SHORTENER && __PDS_MSG_1024 -endif -endif - -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -if (version >= 3.004000) -meta __PDS_URISHORTENER __URL_SHORTENER -endif -endif - -meta __PD_CNT_1 (__PUMPDUMP_01+__PUMPDUMP_02+__PUMPDUMP_03+__PUMPDUMP_04+__PUMPDUMP_05+__PUMPDUMP_06+__PUMPDUMP_07+__PUMPDUMP_08+__PUMPDUMP_09+__PUMPDUMP_10) > 0 - -body __PENDING_MESSAGES /\b(?:messages pending|(?:your|\d+[\])}]?) (?:pending|un(?:delivered|received)) (?:messages|e?-?mails))\b/i - -body __PERFECT_BINARY /\bperfect binary option\b/i - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __PHISH_ATTACH_01_01 Content-Disposition =~ /\bfilename(?:="?[^"]*|\*(?:\d+\*)?=(?:UTF-8'')?\S*)(?:\.|%C2%B7|[\xc2][\xb7]|_)(?:pdf|docx?)\.html?[";$]/i -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __PHISH_ATTACH_01_02 Content-Type =~ /\bname="?[^"]*(?:\.|[\xc2][\xb7]|_)(?:pdf|docx?)\.html?[";$]/i -endif - -meta __PHISH_FBASE_01 (__URI_FIREBASEAPP || __URI_WEBAPP) && __PDS_FROM_NAME_TO_DOMAIN && __MAIL_LINK - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - body __PHOTO_RETOUCHING /\b(?:(?:retouching|(?:image|photo|pic)s? (?:[a-z]{1,15} ){0,3}(?:edit(?:ing|ors)|team|(?:cut+|mask|clip+|clean|crop+|resiz|enhanc|etch)ing|cut+(?:ing)?[-\s]?out|enhancement|manipulation|restoration|compositing|working|(?:color|contrast|brightnes+|background|make-?up) (?:cor+ection|change)|solution|work|services?)|(? 1 - -header __RAND_MKTG_HEADER ALL =~ /^X-(?:[a-z]{2}){1,2}-(?:EBS|(?:Tracking|Subscriber|Delivery|Customer|Campaign)-[DSU]?id):/ism - -header __RATWARE_BOUND_A ALL =~ /^Message-Id: <....([0-9a-f]{8})\$[0-9a-f]{8}\$.{10,400}boundary="----=_NextPart_000_...._\1\./msi # " - -header __RATWARE_BOUND_B ALL =~ /boundary="----=_NextPart_000_...._([0-9a-f]{8})\..{10,400}^Message-Id: <....\1\$[0-9a-f]{8}\$/msi # " - -header __RCD_RDNS_MAIL X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*\bmail[^a-z]/i -tflags __RCD_RDNS_MAIL nice - -header __RCD_RDNS_MAIL_MESSY X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*mail/i -tflags __RCD_RDNS_MAIL_MESSY nice - -header __RCD_RDNS_MTA X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*\bmta[^a-z]/i -tflags __RCD_RDNS_MTA nice - -header __RCD_RDNS_MTA_MESSY X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*mta/i -tflags __RCD_RDNS_MTA_MESSY nice - -header __RCD_RDNS_MX X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*\bmx[^a-z]/i -tflags __RCD_RDNS_MX nice - -header __RCD_RDNS_MX_MESSY X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*mx/ -tflags __RCD_RDNS_MX_MESSY nice - -header __RCD_RDNS_OB X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*\boutbounds?[^a-z]/i -tflags __RCD_RDNS_OB nice - -header __RCD_RDNS_SMTP X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*\bsmtps?[^a-z]/i -tflags __RCD_RDNS_SMTP nice - -header __RCD_RDNS_SMTP_MESSY X-Spam-Relays-External =~ /^[^\]]+ rdns=\S*smtp/ -tflags __RCD_RDNS_SMTP_MESSY nice - -header __RCVD_DOTEDU_EXT X-Spam-Relays-External =~ /\srdns=\S+\.edu\s/i - -meta __RCVD_DOTEDU_SHORT __RCVD_DOTEDU_EXT && ( __HTML_IMG_ONLY || __BODY_URI_ONLY || __HTML_LENGTH_1024_1536 ) - -meta __RCVD_DOTEDU_SUSP_URI __RCVD_DOTEDU_EXT && ( __45_ALNUM_URI || __45_ALNUM_URI_O || __64_ANY_URI ) - -header __RCVD_DOTGOV_EXT X-Spam-Relays-External =~ /\srdns=\S+\.gov\s/i - -header __RCVD_ZIXMAIL X-Spam-Relays-Untrusted =~ / helo=smtpout\.zixmail\.net / - -header __RDNS_LONG X-Spam-Relays-External =~ /^[^\]]+ rdns=\S{30}/ - -header __RDNS_NO_SUBDOM X-Spam-Relays-External =~ /^[^\]]+ rdns=[^. ]*\.\w+ / - -header __RDNS_NUMERIC_TLD X-Spam-Relays-External =~ /\srdns=\S+\.\d+\s/ - -header __RDNS_SHORT X-Spam-Relays-External =~ /^[^\]]+ rdns=\S{4,14} / - -body __RECEIVE_BONUS /\byou(?:'ll)?(?: also| will)* (?:rec[ei]*ve|get|earn|collect|be (?:awarded|handed|remitted|given|paid|(?:greeted|welcomed|started) with)) (?:an? )?(?:gift|bonus|extra)(?: of|:)? \$[\d,]+/i - -header __RELAY_THRU_WWW Received =~ /from (?:[^ \@]+\@)?www\./ - -body __RELEASE_MESSAGES /\b(?:release messages|(?:retrieve|release|download) your(?: undelivered|unreceived|held|pending)? e?-?mails|(?:e?-?mails|messages).{1,20}download them now)\b/i - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader # { - meta __REMOTE_IMAGE (__HTML_IMG_ONLY || __HTML_LINK_IMAGE) && !(__SUBSCRIPTION_INFO || __VIA_ML || __SENDER_BOT || __ANY_IMAGE_ATTACH) -endif - -if (version >= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -header __REPLYTO_ADDRLIST_SUSPNTLD eval:check_replyto_in_list('SUSP_NTLD') -endif -endif - -header __REPTO_419_FRAUD_AOL_LOOSE Reply-To:addr =~ /^(?=[^\s<>@]+\@aol\.com)(?:(?:a(?:f\.|ljaber)|c(?:hanprivacy|laimdept|ristinabruno|ustom_service)|dhodgkins|evelynjoshua|f(?:d\.|ernandezfernandez)|george_clifford|hernandezrosemary|k\.doreen|l(?:erynnewest|ynnpage)|m(?:_l\.wanczyk|asayohara|rsjanetedwards)|officework|paulpollard|royalpalace|spwalker|usembassy|yurdaaytarkan))\d+\@aol\.com$/i - -header __REPTO_419_FRAUD_GM_LOOSE Reply-To:addr =~ /^(?=[^\s<>@]+\@gmail\.com)(?:(?:9porssts|a(?:\.wafager|b(?:dullahmundani|u(?:lkareem|shadi))|cecere|l(?:an\.austin|ex(?:anderpeterson|hoffman)|ghafrij|kasimunadi|l(?:enholden|isoncluade)|ure\.wawrenka)|m(?:bassadormarybethleonardl|ericadeliverycomapny|ina(?:ltwaijiri|medjahed))|n(?:dyfox|na(?:llee|sigurlaug))|office1office|radka|shwestwood|ustinbillmark|zi(?:m(?:\.hpremji|hashim(?:donation)?)|z(?:dake|george)))|b(?:a(?:nkcentralasiahalobca|r(?:bersmadar|risterlordruben|teld\.huisman))|bongo|e(?:alitoniua|linekra|n(?:ezero|gatl|jaminsarah))|ill\.lawrence|mwautomobile|oarddept|rendalaporte|uffettwarrene)|c(?:h(?:a(?:ngching|r(?:itylisajohnrobinson|l(?:esluenga|tonnewmanus)))|e(?:mchung|nchung))|iticonsultantjohncg|laxtonpaul|o(?:lombasjuan|ntactad)|rist(?:brun?|davis|ydavisdonation)|ustomerservicelacaixa)|d(?:a(?:nnuar|vi(?:d(?:\.loanfirm|larbi|pere|ramirez\.luis)|scarolyn|yax))|e(?:nnisclark|partmentofstate)|minique|ona(?:ldwilliam|tionhelpercare)|rdavidrhama|unsilva)|e(?:benezero|christina|l(?:i(?:bethgomez|sabethmaria|zabethedw)|o(?:diesawadogo|tocashoffice))|m(?:efieleg?|ilyrichmond)|re(?:nakgeorge|zcelic)|stherkatherine|wynn)|f(?:\.mikhail|a(?:ithdesrie|tme\.mehmed)|blott|irstbank|r(?:a(?:100dub|n(?:c(?:espatrickconnolly|iscamendoza)|k(?:jane|linpiesie)))|eelottosweepstake)|spero|ulanlan)|g(?:00gleggewinner|a(?:briel(?:eschmitt|kalia)|rciavincent)|bill|e(?:neralwilliamstony|orgekwame|raldjhjh)|iidp|l(?:enmoore|oriachow)|oo(?:golteam|oglegwiinner)|r(?:aceobia|e(?:ant|energeoffrey)))|h(?:a(?:r(?:gate|ryebert)|sh(?:imyreem|mireem))|e(?:atherbrooeke|ctor(?:castillos|scastillo)|lengiggs)|gold|ildad|o(?:nmackjohn|rnbeckmajordennis|seoky))|i(?:bed|mfdeputyoff|n(?:fo\.annedouglas|gridrolle)|smail(?:eman|tarkan))|j(?:a(?:mesokoh|vierlesme)|efferydean|o(?:edward|hn(?:griffn|r(?:awlings|oxfordjr)|sonwilson|uba|walterlove|a)|n(?:athanhaskel|hugo)|sephacevedo|vannyanderson)|rawlings|uliewatson)|k(?:a(?:l(?:iaksandr|tschmidtdavid)|malnizar|rabo\.ramala|t(?:jamess|rinaziako))|ennedy\.sawadogo|halidbuhazza|kasbu|rnkl|un(?:gwei|ioue))|l(?:a(?:rrytoms|ursent|wrencefoundation)|e(?:enasinghs|rynne(?:0west|west))|i(?:amfinchus|fecshortt|liane\.bettencourt|nelink|sa(?:milner|robin))|john|oughreymargaret|u(?:ckywinners|sba\.moored)|y(?:\.cheapiseth|diawright|n(?:\.arthur|cmba|nmkl)))|m(?:a(?:incare|jor(?:dennishornbeck|townsend)|lletman|n(?:duesq|fran|uelfranco(?:(?:donation|foundation|spende))?)|r(?:i(?:ahhills|opabl)|kroth|shalh|tinamayer|y(?:franson|josen))|urhinck|viswan(?:czyk(?:(?:foundation|k))?)?)|c\.cheadychang|dredban|elvidabullock|gfrederick|i(?:c(?:h(?:ael\.woosley|ealwuu)|w)|k(?:e\.weirsky\.foundational|hai(?:\.fridman|lfridm))|ss\.yasmineibrahim)|k(?:ent|untjoro)|oham(?:edabdul|m(?:daljililati|edshamekh))|r(?:\.(?:elbahi\.mohammed\.|justinmaxwell)|cjames|ericschmid|hanimuhammad|jamesmc|richardanthony|s(?:\.susanread|a(?:ishaalqadafi|ngela)|dominiquethomas|evelynbrown|fatimaamiraqureshi|hamima|jackman|lisamilner|maureens|r(?:obinsanders|uthsmith)|sarahbenjamin|victoriaedmond))|s(?:\.ellagolan|agent|golaan|smadar)|ustadris)|n(?:aomiiwasaki|eilt(?:rotter)?|icholas\.jose|obuyuki\.hirano)|o(?:\.peace|fficerricherd|hallkenneth|xfaminternationa)|p(?:aul(?:eed|n)|b(?:ph202lay|rookk)|e(?:rezdonlorenzo|ter(?:\.waddell|guggi|kenin|stephen))|hillip\.richead)|q(?:iquanzhou|nzeng)|r(?:a(?:kidy|lhashimi|ymondaba)|e(?:beccagarang|em(?:has(?:himy|m)|n)|plyback|v(?:\.jamesabel|fr(?:ankjackson|paulwilliams)))|icha(?:miller|rdw(?:ahl|illis))|o(?:b(?:erthanandez|inf)|naldmorris|s(?:a\.gomes|ekipkalya))|raya|t\.rev\.ericmark)|s(?:a(?:l(?:ehhussienconsult|imzaid)|rfiafarfask)|cottpeters|e(?:cretservicce|rgeantrobertbrown)|gt(?:\.monicab|ireneb)|h(?:anemissler|ery(?:\.gtl|etr)|inawatrathaksin)|im(?:lkheng|onhei)|op(?:adam|hiajesse)|peelman|t(?:anleyjohn|ephentam)|u(?:iyang|n\.hor|sanneklatten)|weeneyjohnson)|t(?:a(?:mmywebster|y(?:ebsouami|lorcathy))|erryparkins|h(?:ailandbankoffice|e(?:ara\.choy|odorosloannis))|imothymetheny|lyerdonald|o(?:m(?:ander|c(?:hrist|rist(?:(?:donation|foundation))?)|spende)|ny(?:\.chung|zimpro)|shikazusendo))|u(?:marukareem|n(?:claimedfunds|itednation(?:organization|s))|s(?:alotery|departmentofjustice))|v(?:anderwesthuizen|e(?:enapatel|r(?:a(?:aellen|hollinkvan)|enichekaterinaekaterina))|i(?:ctoriaabraham|dalpamela|ngut))|w(?:a(?:dp|hlr(?:ichard)?|nczykm|rrenebuffett)|hatsappofficial|i(?:elandherzog\.sw\.herad|ll(?:clark|iamsmartyrs))|u\.office|ww\.moneygram)|y(?:\.oguzhan|anghoseok|doo|ousefzongo)|z(?:bank|enithbankplconline|kiaslan|minhong)))\d+\@gmail\.com$/i - -header __REPTO_419_FRAUD_YH_LOOSE Reply-To:addr =~ /^(?=[^\s<>@]+\@yahoo\.com)(?:(?:a(?:driantongson|ilmohammed|lesiakalina|nnhester\.usa)|b(?:ank\.phbng|en(?:jaminb|nicholas)|riceangela)|c(?:\.aroline|h(?:arlesscharf|jackson)|juan|ythiamiller\.un)|dhamilton|e(?:denvictor|ricalbert)|federal\.r|j(?:a(?:ckson\.davis|netemoon)|kimyong)|k(?:altschmidtdavid|elvinmark|im(?:\.leang|leang))|l(?:e(?:a_edem|hman)|isarobinson_|y_cheapiseth)|m(?:\.kogi|arie_avis|dzsesszika|elissalewis|o(?:hammedaahil|keye))|o(?:legkozyrev|mranshaalan)|peterlee|r(?:alphw(?:\.johnson|johnson)|o(?:bertbailey|serichard))|s(?:amthong|igurlauganna|leo|pwalker|te(?:fanopessina|vecox\.))|tylerhess\.|vanserge|will(?:clark|smi)|xianglongdai))\d+\@yahoo\.com$/i - -header __REPTO_CHN_FREEM Reply-To =~ /\@(?:sina|aliyun)\.com/i - -header __REPTO_INFONUMSCOM Reply-To:addr =~ /^info@\d{5,}\.com$/i - -header __REPTO_RUS_FREEM Reply-To =~ /\@mail\.ru/i - -if !((version >= 3.003000)) - meta __RP_MATCHES_RCVD 0 -endif - -if (version >= 3.003000) -if !plugin(Mail::SpamAssassin::Plugin::WLBLEval) - meta __RP_MATCHES_RCVD 0 -endif -endif - -if (version >= 3.003000) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval - header __RP_MATCHES_RCVD eval:check_mailfrom_matches_rcvd() -endif -endif - -body __SCAM /\bscam(?:m?e[dr])?s?\b/i - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __SCC_BOGUS_CTE_1 Content-Transfer-Encoding =~ /^Hexa/i -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __SCC_CTMPP Content-Type =~ /multipart\/parallel/ -endif - -body __SECURITY_DEPT /\bsecurity dep(?:artmen)?t\b/i - -header __SENDER_BOT ALL =~ /(?:not?\W?repl[yi]|bounce|contact|daemon|subscri|report|respon[ds]e?r?s?\b|\b(?:root|news|nobody|agent|(?:post|web)?master|manag|send(?:er|ing)?|out|(?:bot|web|www)\b))[^\@ >]{0,5}s?\@\w/i -tflags __SENDER_BOT nice - -uri __SENDGRID_REDIR m,://u\d+\.ct\.sendgrid\.net/ls/click\?upn=, - -meta __SENDGRID_REDIR_NOPHISH __SENDGRID_REDIR && !__SENDGRID_REDIR_PHISH - -meta __SENDGRID_REDIR_PHISH __SENDGRID_REDIR && ( __PDS_FROM_NAME_TO_DOMAIN || __FORGED_RELAY_MUA_TO_MX || __TO_IN_SUBJ ) - -body __SHARE_IT /\b(?:(?:share|allocate|teilen|parteger(?:ez|ons)?|partage)\s(?:th(?:e|is)|das|les?|des)\s(?:proceeds|funds?|money|balance|account|geld|compte|fonds)|partager(?:ez|ons)? (?:avec (?:vous|moi)|ratio|suivant un pourcentage))\b/i - -meta __SHOPIFY_IMG_NOT_RCVD_SFY __URI_IMG_SHOPIFY && !__HDR_RCVD_SHOPIFY && !__HDR_ENVFROM_SHOPIFY - -uri __SHORT_URL /^https?:\/\/[^\/]{3,6}\.\w\w\/[^\/]{3,8}\/?$/ - -body __SINGLE_WORD_LINE /^\s?\S{1,60}\s?$/ -tflags __SINGLE_WORD_LINE multiple maxhits=2 - -header __SINGLE_WORD_SUBJ Subject =~ /^\s*\S{1,60}\s*$/ - -header __SMIME_MESSAGE Content-Type =~ /application\/pkcs7-mime;/i - -rawbody __SPAN_BEG_TEXT /[a-z]{2}<(?i:span)\s/ -tflags __SPAN_BEG_TEXT multiple maxhits=5 - -rawbody __SPAN_END_TEXT /[^;>]<\/(?i:span)>[a-z]{3}/ -tflags __SPAN_END_TEXT multiple maxhits=5 - -if !plugin(Mail::SpamAssassin::Plugin::SPF) - meta __SPF_FULL_PASS 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::SPF - meta __SPF_FULL_PASS (SPF_PASS && SPF_HELO_PASS) - tflags __SPF_FULL_PASS net -endif - -if !plugin(Mail::SpamAssassin::Plugin::SPF) - meta __SPF_RANDOM_SENDER 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::SPF - meta __SPF_RANDOM_SENDER (SPF_HELO_PASS && !SPF_PASS) - tflags __SPF_RANDOM_SENDER net -endif - -meta __SPOOFED_FREEMAIL !__NOT_SPOOFED && FREEMAIL_FROM -tflags __SPOOFED_FREEMAIL net - -meta __SPOOFED_FREEM_REPTO __SPOOFED_FREEMAIL && FREEMAIL_REPLYTO -tflags __SPOOFED_FREEM_REPTO net - -rawbody __SPOOFED_URL m/]{0,2048}\bhref=(?:3D)?.?(https?:[^>"'\# ]{8,29}[^>"'\# :\/?&=])[^>]{0,2048}>(?:[^<]{0,1024}<(?!\/a)[^>]{1,1024}>){0,99}\s{0,10}(?!\1)https?[^\w<]{1,3}[^<]{5}/i - -meta __STATIC_XPRIO_OLE __XPRIO && __RDNS_STATIC && __HAS_MIMEOLE - -body __STAY_HOME /\b(?:going out of|leaving)(?: your)? (?:home|house|residence)\b/i - -body __STOCK_TIP /\bsto[ck]{2}\s?tip\b/i - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - rawbody __STY_INVIS /\bstyle\s*=\s*"[^">]{0,80}(?:(? 1 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __STY_INVIS_3 __STY_INVIS > 2 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __STY_INVIS_DIRECT __STY_INVIS && __DOS_DIRECT_TO_MX_UNTRUSTED -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __STY_INVIS_MANY __STY_INVIS > 5 -endif - -header __SUBJECT_EMPTY Subject:raw =~ /^\s*$/ - -meta __SUBJECT_PRESENT_EMPTY __HAS_SUBJECT && __SUBJECT_EMPTY - -header __SUBJ_ADMIN Subject =~ /\b(?:(?:sys)?admin(?:istrator)?|server|service|support)\b/i - -header __SUBJ_ATTENTION Subject =~ /ATTENTION/ - -meta __SUBJ_BRKN_WORDNUMS __SUBJ_BROKEN_WORD && __TVD_SUBJ_NUM_OBFU - -header __SUBJ_BROKEN_WORD Subject =~ /\s(?!i[PTM][aoh][bcdou]|e[MP]a[is])[a-z]{1,3}[A-Z][a-z]{2}/ -tflags __SUBJ_BROKEN_WORD multiple maxhits=2 - -meta __SUBJ_DOM_ADMIN __SUBJ_ADMIN && __PDS_FROM_NAME_TO_DOMAIN - -header __SUBJ_HAS_FROM_1 ALL =~ /\nFrom:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*Subject:\s+[^\n]{0,100}\1[>,:\s\n]/ism - -header __SUBJ_HAS_TO_1 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s>,]+)>?\n(?:[^\n]{1,200}\n)*Subject:\s+[^\n]{0,100}\1[^a-z0-9]/ism - -header __SUBJ_HAS_TO_2 ALL =~ /\nReceived:[^\n]{0,200} for ;]+)>?;(?:[^\n]+\n)*Subject:\s+[^\n]{0,100}\1[^a-z0-9]/ism - -header __SUBJ_HAS_TO_3 ALL =~ /\nSubject:(?=[^\n]{0,200}@)[^\n]{0,200}([a-z][a-z0-9_.]{3,80}@(?:[a-z0-9_]{1,80}\.){1,4}[a-z]{2,30})(?:[^\n]+\n)*To:\s+[^\n]{0,100}\1[^a-z0-9.]/ism - -header __SUBJ_NOT_SHORT Subject =~ /^.{16}/ - -header __SUBJ_OBFU_PUNCT Subject =~ /(?:[-~`"!@\#$%^&*()_+={}|\\\/?<>,.:;][a-z][-~`"!@\#$%^&*()_+={}|\\\/?<>,.:;\s]|(?:[a-z][~`"!@\#$%^&*()_+={}|\\?<>,.:;][a-z](?![a-z])))/i -tflags __SUBJ_OBFU_PUNCT multiple maxhits=4 - -header __SUBJ_RE Subject =~ /^(?:R[eE]|S[vV]|V[sS]|A[wW]):/ - -header __SUBJ_SHORT Subject =~ /^.{0,8}$/ - -header __SUBJ_USB_DRIVES Subject =~ /\bUSB (?:[Ff]lash )?[Dd]rives\b/ - -body __SUBSCRIPTION_INFO /\b(?:e?newsletters?|(?:un)?(?:subscrib|register)|you(?:r| are) subscri(?:b|ption)|opt(?:.|ing)?out\b|further info|you do ?n[o']t w(?:ish|ant)|remov\w{1,3}.{1,9}\blists?\b|to your white.?list)/i -tflags __SUBSCRIPTION_INFO nice - -body __SUM_OF_FUND /\b(?:sum|release|freigabe)\s(?:of|der)\s(?:amount|fund|investment|mittel)\b/i - -body __SURVEY /\bsurvey\b/i - -body __SURVIVORS /\b(?:widow|son|daughter|husband|wife|brother|sister|attorney|vi(?:=FA|[\xfa]|[\xc3][\xba])va|esposa|veuve)\s(?:of|to|do|de)\s(?:the\s)?(?:late|falecido|finales|feu|d(?:e|=E9|[\xe9]|[\xc3][\xa9])funt|mr\.?)\s\w+\b/i - -body __SUSPICION_LOGIN /\bsuspicion login\b/i - -body __SYSADMIN /\b(?:help?[- ]?desk|(?:(?:web ?)?mail ?|sys(?:tem )?)admin(?:istrator)|local[- ]host|(?:support|upgrade|management|security|admin(?:istrat(?:or|ion))?) (?:team|center)|message from administrator|university mail server copyright|suporte t(?:=E9|[\xe9]|[\xc3][\xa9])cnico|administrador do sistema)\b/i - -meta __TAGSTAT_IMG_NOT_RCVD_TGST __URI_IMG_TAGSTAT && !__HDR_RCVD_TAGSTAT - -meta __TARINGANET_IMG_NOT_RCVD_TN __URI_IMG_TARINGANET && !__HDR_RCVD_TARINGANET - -header __TB_MIME_BDRY_NO_Z Content-Type =~ /boundary="-{8,}(?:[1-9]){16}/ - -rawbody __TENWORD_GIBBERISH /^\s*(?:[a-z]+\s+){10}\.$/m -tflags __TENWORD_GIBBERISH multiple maxhits=21 - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __TEXT_XML_MT Content-Type =~ m,\btext/xml\b,i -endif - -body __THEY_INHERIT /\b(?:inherit\sth(?:e|is)\smoney|herede\sest[ea]\sdinero)\b/i - -body __THIS_AD /(?:\b|_)this[- _]+(?:ad(?:vert[i1l]sement)?|promo(?:tion)?)s?(?:\b|_)/i - -meta __THREADED (!__MISSING_REPLY && !__NO_INR_YES_REF) || (__MISSING_REPLY && !__MISSING_REF) -tflags __THREADED nice - -header __THREAD_INDEX_GOOD Thread-Index =~ m,^A[a-z0-9][A-Za-z0-9+/]{27}(?:[A-Za-z0-9+/]{20})?(?:[AQgw]==|[A-Za-z0-9+/]{7}|[A-Za-z0-9+/]{13}[AEIMQUYcgkosw048]=)$, - -header __TO_ALL_NUMS To:addr =~ /^\d+@/ - -meta __TO_EQ_FM_DIRECT_MX __TO_EQ_FROM && __DOS_DIRECT_TO_MX - -if !plugin(Mail::SpamAssassin::Plugin::SPF) - meta __TO_EQ_FM_DOM_SPF_FAIL 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::SPF - meta __TO_EQ_FM_DOM_SPF_FAIL __TO_EQ_FROM_DOM && SPF_FAIL - tflags __TO_EQ_FM_DOM_SPF_FAIL net -endif - -if !plugin(Mail::SpamAssassin::Plugin::SPF) - meta __TO_EQ_FM_SPF_FAIL 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::SPF - meta __TO_EQ_FM_SPF_FAIL __TO_EQ_FROM && SPF_FAIL - tflags __TO_EQ_FM_SPF_FAIL net -endif - -meta __TO_EQ_FROM (__TO_EQ_FROM_1 || __TO_EQ_FROM_2) -describe __TO_EQ_FROM To: same as From: - -header __TO_EQ_FROM_1 ALL =~ /\nFrom:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*To:\s+(?:[^\n]{0,80}<)?\1[>,\s\n]/ism - -header __TO_EQ_FROM_2 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*From:\s+(?:[^\n]{0,80}<)?\1[>,\s\n]/ism - -meta __TO_EQ_FROM_DOM (__TO_EQ_FROM_DOM_1 || __TO_EQ_FROM_DOM_2) -describe __TO_EQ_FROM_DOM To: domain same as From: domain - -header __TO_EQ_FROM_DOM_1 ALL =~ /\nFrom:\s+[^\n@]{0,80}@([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*To:\s+[^\n]+@\1[>,\s\n]/ism - -header __TO_EQ_FROM_DOM_2 ALL =~ /\nTo:\s+[^\n@]{0,80}@([^\n\s>]+)>?\n(?:[^\n]{1,100}\n)*From:\s+[^\n]+@\1[>,\s\n]/ism - -meta __TO_EQ_FROM_USR (__TO_EQ_FROM_USR_1 || __TO_EQ_FROM_USR_2) && !(__FROM_DNS || __FROM_INFO || __SENDER_BOT) -describe __TO_EQ_FROM_USR To: username same as From: username - -header __TO_EQ_FROM_USR_1 ALL =~ /\nFrom:\s+(?:[^\n<]{0,80}<)?([^\n\s\@>]+)\@[^\n\s]+>?\n(?:[^\n]{1,100}\n)*To:\s+(?:[^\n]{0,80}<)?\1[\@>,\s\n]/ism - -header __TO_EQ_FROM_USR_2 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s\@>]+)\@[^\n\s]+>?\n(?:[^\n]{1,100}\n)*From:\s+(?:[^\n]{0,80}<)?\1[\@>,\s\n]/ism - -meta __TO_EQ_FROM_USR_NN (__TO_EQ_FROM_USR_NN_1 || __TO_EQ_FROM_USR_NN_2) && !(__FROM_DNS || __FROM_INFO || __SENDER_BOT) -describe __TO_EQ_FROM_USR_NN To: username same as From: username sans trailing nums - -header __TO_EQ_FROM_USR_NN_1 ALL =~ /\nFrom:\s+(?:[^\n<]{0,80}<)?([^\n\s\@>]{4,80}?)\d*\@[^\n\s]+>?\n(?:[^\n]{1,100}\n)*To:\s+(?:[^\n]{0,80}<)?\1\d*[\@>,\s\n]/ism - -header __TO_EQ_FROM_USR_NN_2 ALL =~ /\nTo:\s+(?:[^\n<]{0,80}<)?([^\n\s\@>]{4,80}?)\d*\@[^\n\s]+>?\n(?:[^\n]{1,100}\n)*From:\s+(?:[^\n]{0,80}<)?\1\d*[\@>,\s\n]/ism - -meta __TO_EQ_FROM_USR_NN_MINFP __TO_EQ_FROM_USR_NN && !__TO_EQ_FROM_USR_1 && !__TO_EQ_FROM && !__TO_EQ_FROM_DOM && !__LCL__ENV_AND_HDR_FROM_MATCH && !__DKIM_EXISTS && !__NOT_SPOOFED && !__RCD_RDNS_SMTP && !__RCD_RDNS_MX_MESSY && !__THREADED - -meta __TO_IN_SUBJ (__SUBJ_HAS_TO_1 || __SUBJ_HAS_TO_2 || __SUBJ_HAS_TO_3) - -header __TO_NO_ARROWS_R To !~ /(?:>$|>,)/ - -if !plugin(Mail::SpamAssassin::Plugin::FreeMail) - meta __TO_NO_BRKTS_FREEMAIL 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - meta __TO_NO_BRKTS_FREEMAIL __TO_NO_ARROWS_R && (FREEMAIL_FROM || FREEMAIL_REPLYTO) -endif - -meta __TO_NO_BRKTS_FROM_RUNON __TO_NO_ARROWS_R && !__TO_UNDISCLOSED && __FROM_RUNON - -meta __TO_NO_BRKTS_HTML_IMG __TO_NO_ARROWS_R && !__TO_UNDISCLOSED && HTML_MESSAGE && __ONE_IMG - -meta __TO_NO_BRKTS_HTML_ONLY __TO_NO_ARROWS_R && !__TO_UNDISCLOSED && MIME_HTML_ONLY - -meta __TO_NO_BRKTS_MSFT __TO_NO_ARROWS_R && !__TO_UNDISCLOSED && (__ANY_OUTLOOK_MUA || __MIMEOLE_MS) - -meta __TO_NO_BRKTS_NORDNS_HTML __TO_NO_BRKTS_HTML_ONLY && RDNS_NONE - -meta __TO_NO_BRKTS_PCNT __TO_NO_ARROWS_R && __FB_NUM_PERCNT - -meta __TO_TOO_MANY_WFH_01 __TO_WAY_TOO_MANY && __WFH_01 - -header __TO_UNDISCLOSED To =~ /\b(?:undisclosed[-\s]recipients|destinataires inconnus|destinatari nascosti)\b/i - -header __TO_WAY_TOO_MANY ToCc =~ /(?:,[^,]{1,90}){50}/ - -body __TO_YOUR_ACCT /\b(?:(?:f[uo]nds|money|f[uo]ndo|dinheiro|bank)\s(?:\w{1,10}\s){0,4}(?:transfer(?:red)?|transferido|sont)|\d+)\s(?:to|para|en)\s(?:your?|sua|votre)\s(?:account|conta|pos+es+ion)/i - -body __TO_YOUR_ORG /\b(?:to|for) your organi[sz]ation\b/i - -header __TO___LOWER ALL =~ /to:\s\S{5}/ - -body __TRANSFORM_LIFE /\b(transform|change) your (?:daily )?life(?:style)?\b/i - -body __TRAVEL_AGENT /\btravel\sagen(?:t|cy)\b/i - -body __TRAVEL_BUSINESS /\bbusiness\stravel\b/i - -body __TRAVEL_ITINERARY /(?:travel|ticketed|your|current) itinerary/i - -meta __TRAVEL_MANY (__TRAVEL_PROFILE + __TRAVEL_RESERV + __TRAVEL_BUSINESS + __TRAVEL_AGENT) > 2 - -body __TRAVEL_PROFILE /\btravel+er\sprofile\b/i - -body __TRAVEL_RESERV /\b(?:reservation\s(?:confirmed|number)|travel\sreservations?)\b/i - -body __TRTMT_DEFILED /\bdefiled\sall\s(?:forms\sof\s)?(?:medical\s)?treatments?\b/i - -body __TRUNK_BOX /\b(?:(?:trunk|metallic|proof|security|consignment)\sbox(?:es)?|sealed\ssafe|une mallette m(?:e|=E9|[\xe9]|[\xc3][\xa9])tallique)\b/i - -body __TRUSTED_CHECK /\b(?:cashier'?s?|certified)\sche(?:ck|que)/i - -rawbody __TR_JS_CONCATINATED_HTTP m@\b(?!http:/)h["'+]{0,3}(?:t["'+]{0,3}){2}p['"+]{0,3}:['"+]{0,3}/@ -describe __TR_JS_CONCATINATED_HTTP Contains concatenated URI like "htt"+"p://..." - -rawbody __TR_JS_EXTRA_CONCAT /[+=(]\s{0,9}["'][a-z0-9.]{1,32}["'] ?\+ ?["'][a-z0-9]{1,32}["']/i -describe __TR_JS_EXTRA_CONCAT JavaScript: Unnecessary string concatenation - -rawbody __TR_JS_EXTRA_UNESCAPE /[+=(]\s{0,9}unescape\s{0,9}\(\s{0,9}["']%(?i:6[1-9A-F]|7[0-9A])/ -describe __TR_JS_EXTRA_UNESCAPE JavaScript: Unnecessary URI escaping - -header __TT_BROKEN_VALIUM Subject =~ /V[:^."%()*\[\\]?A[:^."%()*\[\\]?L[:^."%()*\[\\]?I[:^."%()*\[\\]?U[:^."%()*\[\\]?M/i - -header __TT_BROKEN_VIAGRA Subject =~ /V[:^."%()*\[\\]?I[:^."%()*\[\\]?A[:^."%()*\[\\]?G[:^."%()*\[\\]?R[:^."%()*\[\\]?A/i - -header __TT_OBSCURED_VALIUM Subject =~ /(v|V|\\\/)(a|A|\(a\)|4|@)(l|L|\|)(i|I|1|\xef|\|)(u|U|\(u\))(m|M)/ - -header __TT_OBSCURED_VIAGRA Subject =~ /(v|V|\\\/)(i|I|1|\xef|\|)(a|A|\(a\)|4|@)(g|G)(r|R)(a|A|\(a\)|4|@)/ - -header __TT_VALIUM Subject =~ /VALIUM/i - -header __TT_VIAGRA Subject =~ /VIAGRA/i - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __TVD_FW_GRAPHIC_ID1 Content-Id =~ /<[0-9a-f]{12}(?:\$[0-9a-f]{8}){2}\@/ -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __TVD_MIME_ATT_AOPDF Content-Type =~ /^application\/octet-stream.*\.pdf/i -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __TVD_MIME_ATT_AP Content-Type =~ /^application\/pdf/i -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __TVD_MIME_ATT_TP Content-Type =~ /^text\/plain/i -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader -mimeheader __TVD_OUTLOOK_IMG Content-Id =~ / 9 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - body __UNICODE_OBFU_ZW /[a-z0-9\s](?:\x9d|\xe2\x80[\x8b\x8c\x8d]|\xef\xbb\xbf)+(?!\s)[a-z0-9\s]{1,8}(?:\x9d|\xe2\x80[\x8b\x8c\x8d]|\xef\xbb\xbf)+[a-z0-9\s]/i - tflags __UNICODE_OBFU_ZW multiple maxhits=10 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __UNICODE_OBFU_ZW_10 __UNICODE_OBFU_ZW > 9 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __UNICODE_OBFU_ZW_2 __UNICODE_OBFU_ZW > 1 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __UNICODE_OBFU_ZW_3 __UNICODE_OBFU_ZW > 2 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __UNICODE_OBFU_ZW_5 __UNICODE_OBFU_ZW > 4 -endif - -body __UNSUB_EMAIL /\b(?:(?:un)?subscri(?:ber?|ptions?)|abuses?|opt(?:ing)?.?out)\b[-a-z_0-9.+=]{0,60}\@[a-z0-9][-a-z_0-9.]{4,20}(?:[^a-z_0-9.-]|$)/i -tflags __UNSUB_EMAIL nice - -body __UNSUB_GOOG_FORM m,Unsub?sc?ribe\s= 3.004002) -ifplugin Mail::SpamAssassin::Plugin::WLBLEval -header __VPSNUMBERONLY_TLD From:addr =~ /\@vps[0-9]{4,}\.[a-z]+$/i -endif -endif - -meta __WALMART_IMG_NOT_RCVD_WAL __URI_IMG_WALMART && !__HDR_RCVD_WALMART - -body __WEBMAIL_ACCT /\byour web ?mail account/i - -body __WE_PAID /\bwe have (?:already )?(?:paid|sent|remitted|issued) \$?\d+(?:,\d+)* (?:thousand )?(?:dollars )?to our (?:users|subscribers|members|clients|affiliates|partners)\b/i - -meta __WFH_01 ( __PERFECT_BINARY + __WE_PAID + __MAKE_XTRA_DOLLAR + __BONUS_LAST_DAY + __PASSIVE_INCOME + __WITHOUT_EFFORT + __TRANSFORM_LIFE + __STAY_HOME + __RECEIVE_BONUS ) > 2 - -body __WIDOW /\b(?:widow(?:e[rd])'?s?|veuve)\b/i - -body __WILL_LEGAL /\b(?:codicil|last\stestament|probate|executor|intestate|bequest|mandamus)\b/i - -body __WIRE_XFR /\b(?:wire|telegraph(?:ic)?|bank)\s?transfer/i - -body __WITHOUT_EFFORT /\bwith(?:out(?: a(?:ny)?| the)?| no)(?: great| special| extra)? effort\b/i - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - rawbody __WORD_INVIS /<(?!style)[a-z]+\s[^>]{1,80}(?:font(?:-size)?\s*:\s*(?:0*[01](?:\.\d+)?(?:px|pt|Q|vw|vh|vmin)|0+(?:\.\d+)?(?:cm|mm|in|pc|em|ex|ch|rem|lh|vmax))\s*[;'a-z]|['"\s;]color\s*:\s*transparent\s*[;'])[^>]{0,80}>\w{1,20} 1 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __WORD_INVIS_5 __WORD_INVIS > 5 -endif - -if can(Mail::SpamAssassin::Conf::feature_bug6558_free) - meta __WORD_INVIS_MINFP __WORD_INVIS && !__SURVEY && !MIME_QP_LONG_LINE && !__FB_TOUR && !__MSGID_GUID -endif - -header __XEROXWORKCTR_MUA X-Mailer =~ /^WorkCentre \D?\d[\d\.]\d+/ - -meta __XFER_LOTSA_MONEY __XFER_MONEY && LOTS_OF_MONEY - -meta __XFER_MONEY (__WIRE_XFR || __TRUSTED_CHECK || __BANK_DRAFT || __MOVE_MONEY || __TO_YOUR_ACCT || __PAY_YOU || __GIVE_MONEY) - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - header __XMAIL_CODEIGN X-Mailer =~ /CodeIgniter/ -endif - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - header __XMAIL_PHPMAIL X-Mailer =~ /PHPMailer/ -endif - -header __XM_APPLEMAIL X-Mailer =~ /^Apple Mail/ - -header __XM_ASPQMAIL X-Mailer =~ /^AspQMail/ - -header __XM_BALSA X-Mailer =~ /^Balsa \d/ - -header __XM_CALYPSO X-Mailer =~ /^Calypso/ - -header __XM_DIGITS_ONLY X-Mailer =~ /^\s*\d+\s*$/ - -header __XM_EC_MESSENGER X-Mailer =~ /\beC-Messenger\b/ - -header __XM_FORTE X-Mailer =~ /^Forte Agent \d/ - -header __XM_GNUS X-Mailer =~ /^Gnus v/ - -header __XM_MHE X-Mailer =~ /^mh-e \d/ - -header __XM_MOZ4 X-Mailer =~ /^Mozilla 4/ - -header __XM_MSOE5 X-Mailer =~ /^Microsoft Outlook Express 5/ - -header __XM_MSOE6 X-Mailer =~ /^Microsoft Outlook Express 6/ - -header __XM_MS_IN_GENERAL X-Mailer =~ /\bMSCRM\b|Microsoft (?:CDO|Outlook|Office Outlook)\b/ - -header __XM_OL_10_0_4115 X-Mailer =~ /^Microsoft Outlook, Build 10.0.4115$/ - -header __XM_OL_28001441 X-Mailer =~ /^Microsoft Outlook Express 6.00.2800.1441$/ - -header __XM_OL_28004682 X-Mailer =~ /^Microsoft Outlook Express 6.00.2800.4682$/ - -header __XM_OL_48072300 X-Mailer =~ /^Microsoft Outlook Express 5.50.4807.2300$/ - -header __XM_OL_4_72_2106_4 X-Mailer =~ /^Microsoft Outlook Express 4.72.2106.4$/ - -header __XM_OUTLOOK_EXPRESS X-Mailer =~ /^Microsoft Outlook Express \d/ - -header __XM_PHPMAILER_FORGED X-Mailer =~ /PHPMailer\s.*version\D+$/ - -header __XM_RANDOM X-Mailer =~ /q(?!(?:q|box|i\s)?mail|\d|[-\w]*=+;)[^u]/i - -header __XM_SKYRI X-Mailer =~ /^SKYRiXgreen/ - -header __XM_SQRLMAIL X-Mailer =~ /^SquirrelMail/ - -header __XM_SYLPHEED X-Mailer =~ /^Sylpheed/ - -header __XM_UC_ONLY X-Mailer =~ /^[^a-z]+$/ - -header __XM_VERY_LONG X-Mailer =~ /.{50}/ - -header __XM_VM X-Mailer =~ /^VM \d/ - -header __XM_WWWMAIL X-Mailer =~ /^WWW-Mail \d/ - -header __XM_XIMEVOL X-Mailer =~ /^Ximian Evolution/ - -meta __XPRIO_MINFP __XPRIO && !__CT_ENCRYPTED && !ALL_TRUSTED && !__HAS_ERRORS_TO && !__HAS_IMG_SRC && !__RCD_RDNS_MAIL_MESSY && !__VIA_ML && !__PHPMAILER_MUA && !__AC_TINY_FONT && !__HAS_PHP_SCRIPT && !__DOS_HAS_LIST_UNSUB && !__HAS_IMG_SRC_ONECASE && !__NAKED_TO && !__HAS_THREAD_INDEX && !__HAS_TNEF && !__HAS_SENDER && !__UNPARSEABLE_RELAY_COUNT && !__PDS_RDNS_MTA && !__RCD_RDNS_SMTP_MESSY && !__RCD_RDNS_MX_MESSY && !__TO___LOWER && !__FROM_WORDY && !__RP_MATCHES_RCVD && !__DKIM_EXISTS && !__FROM_WEB_DAEMON && !__RDNS_SHORT && !__L_BODY_8BITS && !__HAS_X_SENDER - -meta __XPRIO_SHORT_SUBJ __XPRIO_MINFP && __SUBJ_SHORT - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __X_MSO_MT Content-Type =~ m,\bapplication/x-mso\b,i -endif - -body __YOUR_BANK /\byour?\s(?:full\s)?bank(?:ing)?\sinformations?\b/i - -body __YOUR_CONSIGNMENT /\b(?:received?|pa(?:y|id)|sen[dt]|h[oe]ld|delay(?:ed)?|impound(?:ed)?|released?|ship(?:ped)?)\syour(?:\s\w+)?\sconsignment\b/i - -body __YOUR_FUND /\b(?:your|ihr)\s(?:unpaid\s|win+ing\s|ap+roved\s|foreign\s|overdue\s|outstanding\s|contract\s|inheritance\s|nicht\sausbezahlten\s){0,3}(?:fund|f\su\sn\sd|payment|geld)\b/i - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __YOUR_ONAN /\b(?:your?|ihrer)\s(?:ma+s+t+[ur]+b+a+t+(?:ion|ing|e)(?:svideo)?|onanism|solitary\ssex|hand\sfucking|Selbstbefriedigung|(?:pleasur(?:e|ing)|satisfy(?:ing)?)\syourself)\b/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __YOUR_ONAN /(?:^|\s)(?:?|)\s(?:++++(?:|)++++(?:||)(?:)?||\s|\s||(?:

(?:|)|(?:)?)\s)/i -endif - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __YOUR_PASSWORD /\b(?:your|(?:change|modify|update|reset|alter|fix)\sthe)\s(?:account\s|e-?mail\s)?(?:pass[-\s_]?word|pswd)\b/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __YOUR_PASSWORD /(?:^|\s)(?:|(?:||

|||)\s)\s(?:\s|-?\s)?(?:

[-\s_]?|

\s)/i -endif - -body __YOUR_PERM /\byour\spermission\b/i - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __YOUR_PERSONAL /\b(?:your\s(?:personal|private|social\scontact|address|friends)\s(?:info(?:rmation)?|data|details|book|secrets)|all\s(?:of\s)?your\s(?:files|contacts|secrets|correspondence))\b/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __YOUR_PERSONAL /(?:^|\s)(?:\s(?:

|

|\s||)\s(?:(?:)?||||)|\s(?:\s)?\s(?:|||

))[\s\.,]/i -endif - -body __YOUR_PROFIT /\byour?\sprofit/i - -if !plugin(Mail::SpamAssassin::Plugin::ReplaceTags) - body __YOUR_WEBCAM /\b(?:from|your|with|and|on)\s(?:(?:screen|desktop|microphone)\sand\s|own\s)?(?:web[-\s]?|front[-\s]?|network\s|your\s)camer+a/i -endif - -ifplugin Mail::SpamAssassin::Plugin::ReplaceTags - body __YOUR_WEBCAM /(?:^|\s)(?:||||)\s(?:(?:|

|

)\s\s|\s)?(?:[-\s]?|[-\s]?|\s|\s)+/i -endif - -body __YOU_ASSIST /\b(?:your\sas+istan(?:ce|t)|votre\s(?:as+istance|aide))\b/i - -body __YOU_INHERIT /\byour\s[a-z\s]{0,30}inherit+ance\b/i - -meta __YOU_WON __YOU_WON_01 || __YOU_WON_02 || __YOU_WON_03 || __YOU_WON_04 || __HAS_WON_01 || (__YOU_WON_05 && (__MOVE_MONEY || __GIVE_MONEY)) - -body __YOU_WON_01 /\byou(?:r|'re|'ve|'ll|\shave|\sdid)?\s(?:e-?mail\s)?(?:\w+\s){0,2}(?:a\s)?w[io]n+(?:er|ing)?(?!\xe2\x80\x99t)(?![`'\x92]t)\b/i - -body __YOU_WON_02 /\bw[io]n\s(?:(?:for|by)\s)?your?\b/i - -body __YOU_WON_03 /\b(?:your?|win+ing|win+ers?|beneficiaries|participants?|individuals?|address(?:es)?|accounts?|emails?)(?:\s[-a-z\s]{4,40})?\s(?:w(?:ere|as)|ha(?:ve|s) be(?:en)?)\s(?:automatically\s)?(?:(?:randomly|raffly)\s(?:selected|cho+sen|cho+sing|picked)|(?:selected|cho+sen|cho+sing|picked)\s(?:[a-z\s]{2,40}?\srandom(?:ly)?|online|lottery|computer\s(?:ballot|wahlgang))|(?:selected|cho+sen|cho+sing|picked)(?:\sas?|\sthe){0,3}\swin+er)/i - -body __YOU_WON_04 /\bqu[ei]\s?(?:vous (?:[\xc3][\xaa]|=C3=AA|[\xea]|e)tes\s?gagnant|en\scons(?:e|=E9|[\xe9]|[\xc3][\xa9])quence\sgagne)\b/i - -body __YOU_WON_05 /\bI won(?!\xe2\x80\x99t)(?![`'\x92]t)\b/i - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __ZIP_ATTACH_MT 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __ZIP_ATTACH_MT Content-Type =~ m,\bapplication/(?:zip|x-(?:zip-)?compress(?:ed)?)\b,i -endif - -if !plugin(Mail::SpamAssassin::Plugin::MIMEHeader) - meta __ZIP_ATTACH_NOFN 0 -endif - -ifplugin Mail::SpamAssassin::Plugin::MIMEHeader - mimeheader __ZIP_ATTACH_NOFN Content-Type =~ m,\bapplication/(?:zip|x-(?:zip-)?compress(?:ed)?)[;\s]*$,i -endif - -ifplugin Mail::SpamAssassin::Plugin::FreeMail - header __freemail_mailreplyto eval:check_freemail_header('Mail-Reply-To') -endif - -body __hk_bigmoney /(?:EURO?|USD?|GBP|CFA|\&\#163;|[\xa3\xa4]|\$|sum of).{0,4}(?:[0-9]{3}[^0-9a-z]?[0-9]{3}|[0-9.,]{1,4}(?: ?M\b| ?(?:de )?Mil))/i - -ifplugin Mail::SpamAssassin::Plugin::FreeMail -header __smf_freemail_hdr_replyto eval:check_freemail_header('Reply-To:addr') -endif diff --git a/resources/spamassassin/72_scores.cf b/resources/spamassassin/72_scores.cf deleted file mode 100644 index 600b25a7..00000000 --- a/resources/spamassassin/72_scores.cf +++ /dev/null @@ -1,407 +0,0 @@ -score AC_BR_BONANZA 0.001 0.001 0.001 0.001 -score AC_DIV_BONANZA 0.001 0.001 0.001 0.001 -score AC_FROM_MANY_DOTS 2.999 2.999 2.999 2.999 -score AC_HTML_NONSENSE_TAGS 1.999 1.999 1.999 1.999 -score AC_POST_EXTRAS 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS1 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS10 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS11 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS12 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS2 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS3 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS4 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS8 1.000 1.000 1.000 1.000 -score AC_SPAMMY_URI_PATTERNS9 1.000 1.000 1.000 1.000 -score ADMITS_SPAM 3.299 0.001 3.299 0.001 -score ADULT_DATING_COMPANY 10.000 10.000 10.000 10.000 -score ADVANCE_FEE_2_NEW_FORM 1.000 1.000 1.000 1.000 -score ADVANCE_FEE_2_NEW_FRM_MNY 1.000 1.000 1.000 1.000 -score ADVANCE_FEE_2_NEW_MONEY 1.999 1.999 1.999 1.999 -score ADVANCE_FEE_3_NEW 2.350 2.776 2.350 2.776 -score ADVANCE_FEE_3_NEW_MONEY 0.488 2.599 0.488 2.599 -score ADVANCE_FEE_4_NEW 2.499 2.399 2.499 2.399 -score ADVANCE_FEE_4_NEW_MONEY 2.126 0.001 2.126 0.001 -score ADVANCE_FEE_5_NEW_FRM_MNY 0.841 2.499 0.841 2.499 -score ADVANCE_FEE_5_NEW_MONEY 0.001 0.001 0.001 0.001 -score AD_PREFS 0.499 0.001 0.499 0.001 -score ALIBABA_IMG_NOT_RCVD_ALI 1.000 1.000 1.000 1.000 -score AMAZON_IMG_NOT_RCVD_AMZN 0.001 0.001 0.001 0.001 -score APP_DEVELOPMENT_FREEM 1.000 1.000 1.000 1.000 -score APP_DEVELOPMENT_NORDNS 1.000 1.000 1.000 1.000 -score ARC_SIGNED 0.001 0.001 0.001 0.001 -score ARC_VALID 0.001 0.001 0.001 0.001 -score AXB_XMAILER_MIMEOLE_OL_024C2 0.001 0.001 0.001 0.001 -score AXB_X_FF_SEZ_S 2.499 2.699 2.499 2.699 -score BAT_BDRY_TO_MALF 2.499 2.499 2.499 2.499 -score BEBEE_IMG_NOT_RCVD_BB 1.000 1.000 1.000 1.000 -score BIGNUM_EMAILS_FREEM 0.001 0.001 0.001 0.001 -score BIGNUM_EMAILS_MANY 2.999 2.999 2.999 2.999 -score BITCOIN_BOMB 1.000 1.000 1.000 1.000 -score BITCOIN_DEADLINE 2.999 2.278 2.999 2.278 -score BITCOIN_EXTORT_01 2.102 1.793 2.102 1.793 -score BITCOIN_EXTORT_02 1.000 1.000 1.000 1.000 -score BITCOIN_IMGUR 1.000 1.000 1.000 1.000 -score BITCOIN_MALF_HTML 2.834 0.776 2.834 0.776 -score BITCOIN_MALWARE 1.670 0.001 1.670 0.001 -score BITCOIN_OBFU_SUBJ 1.000 1.000 1.000 1.000 -score BITCOIN_ONAN 1.146 2.042 1.146 2.042 -score BITCOIN_PAY_ME 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_01 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_02 1.436 0.696 1.436 0.696 -score BITCOIN_SPAM_03 2.499 2.500 2.499 2.500 -score BITCOIN_SPAM_04 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_05 0.001 1.565 0.001 1.565 -score BITCOIN_SPAM_06 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_07 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_08 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_09 1.499 1.499 1.499 1.499 -score BITCOIN_SPAM_10 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_11 1.000 1.000 1.000 1.000 -score BITCOIN_SPAM_12 1.000 1.000 1.000 1.000 -score BITCOIN_SPF_ONLYALL 0.001 1.000 0.001 1.000 -score BITCOIN_XPRIO 0.510 0.001 0.510 0.001 -score BITCOIN_YOUR_INFO 1.395 1.916 1.395 1.916 -score BODY_URI_ONLY 1.153 0.484 1.153 0.484 -score BOGUS_MIME_VERSION 1.000 1.000 1.000 1.000 -score BOGUS_MSM_HDRS 1.000 1.000 1.000 1.000 -score BOMB_FREEM 1.000 1.000 1.000 1.000 -score BOMB_MONEY 1.000 1.000 1.000 1.000 -score BTC_ORG 1.000 1.000 1.000 1.000 -score BULK_RE_SUSP_NTLD 0.920 1.000 0.920 1.000 -score CANT_SEE_AD 1.000 1.000 1.000 1.000 -score CK_HELO_GENERIC 0.250 0.249 0.250 0.249 -score COMMENT_GIBBERISH 1.000 1.000 1.000 1.000 -score COMPENSATION 1.000 0.001 1.000 0.001 -score CONTENT_AFTER_HTML 1.000 1.000 1.000 1.000 -score CONTENT_AFTER_HTML_WEAK 1.000 1.000 1.000 1.000 -score CTE_8BIT_MISMATCH 0.999 0.001 0.999 0.001 -score DATE_IN_FUTURE_Q_PLUS 2.699 2.699 2.699 2.699 -score DAY_I_EARNED 1.000 1.000 1.000 1.000 -score DEAR_BENEFICIARY 1.865 1.387 1.865 1.387 -score DKIMWL_BL 0.001 1.000 0.001 1.000 -score DKIMWL_BLOCKED 0.001 0.001 0.001 0.001 -score DKIMWL_WL_HIGH 0.001 -0.001 0.001 -0.001 -score DKIMWL_WL_MED 0.001 -0.001 0.001 -0.001 -score DKIMWL_WL_MEDHI 0.001 -0.214 0.001 -0.214 -score DOTGOV_IMAGE 1.000 1.000 1.000 1.000 -score DX_TEXT_03 1.699 1.799 1.699 1.799 -score DYNAMIC_IMGUR 1.000 1.000 1.000 1.000 -score EBAY_IMG_NOT_RCVD_EBAY 1.000 1.000 1.000 1.000 -score ENCRYPTED_MESSAGE -1.000 -0.999 -1.000 -0.999 -score END_FUTURE_EMAILS 2.500 2.499 2.500 2.499 -score ENVFROM_GOOG_TRIX 1.000 1.000 1.000 1.000 -score FACEBOOK_IMG_NOT_RCVD_FB 1.000 1.000 1.000 1.000 -score FBI_MONEY 1.000 0.001 1.000 0.001 -score FBI_SPOOF 1.000 1.109 1.000 1.109 -score FILL_THIS_FORM 0.799 0.699 0.799 0.699 -score FONT_INVIS_DIRECT 0.001 0.001 0.001 0.001 -score FONT_INVIS_DOTGOV 1.000 1.000 1.000 1.000 -score FONT_INVIS_HTML_NOHTML 1.000 1.000 1.000 1.000 -score FONT_INVIS_LONG_LINE 2.999 3.000 2.999 3.000 -score FONT_INVIS_MSGID 1.762 1.942 1.762 1.942 -score FONT_INVIS_NORDNS 0.001 1.614 0.001 1.614 -score FONT_INVIS_POSTEXTRAS 0.155 1.389 0.155 1.389 -score FORM_FRAUD 0.001 1.000 0.001 1.000 -score FORM_FRAUD_3 2.399 0.001 2.399 0.001 -score FORM_FRAUD_5 0.889 0.001 0.889 0.001 -score FOUND_YOU 1.000 1.000 1.000 1.000 -score FREEMAIL_FORGED_FROMDOMAIN 0.249 0.001 0.249 0.001 -score FREEM_FRNUM_UNICD_EMPTY 1.000 1.000 1.000 1.000 -score FRNAME_IN_MSG_XPRIO_NO_SUB 1.000 1.000 1.000 1.000 -score FROM_2_EMAILS_SHORT 0.001 1.306 0.001 1.306 -score FROM_ADDR_WS 1.000 2.999 1.000 2.999 -score FROM_BANK_NOAUTH 0.001 1.000 0.001 1.000 -score FROM_FMBLA_NDBLOCKED 0.001 0.001 0.001 0.001 -score FROM_FMBLA_NEWDOM 0.001 1.500 0.001 1.500 -score FROM_FMBLA_NEWDOM14 0.001 1.000 0.001 1.000 -score FROM_FMBLA_NEWDOM28 0.001 0.799 0.001 0.799 -score FROM_GOV_DKIM_AU 0.001 -0.001 0.001 -0.001 -score FROM_GOV_REPLYTO_FREEMAIL 0.001 1.000 0.001 1.000 -score FROM_GOV_SPOOF 0.001 1.000 0.001 1.000 -score FROM_MISSPACED 2.000 1.999 2.000 1.999 -score FROM_MISSP_EH_MATCH 1.999 1.595 1.999 1.595 -score FROM_MISSP_FREEMAIL 0.001 1.017 0.001 1.017 -score FROM_MISSP_MSFT 0.001 0.001 0.001 0.001 -score FROM_MISSP_REPLYTO 2.198 0.001 2.198 0.001 -score FROM_MISSP_SPF_FAIL 0.001 0.185 0.001 0.185 -score FROM_MISSP_USER 0.001 0.001 0.001 0.001 -score FROM_MULTI_NORDNS 1.786 1.002 1.786 1.002 -score FROM_NEWDOM_BTC 0.001 1.000 0.001 1.000 -score FROM_NTLD_LINKBAIT 1.000 1.000 1.000 1.000 -score FROM_NTLD_REPLY_FREEMAIL 1.000 1.000 1.000 1.000 -score FROM_NUMBERO_NEWDOMAIN 0.001 1.000 0.001 1.000 -score FROM_PAYPAL_SPOOF 0.001 1.599 0.001 1.599 -score FROM_SUSPICIOUS_NTLD 0.499 0.499 0.499 0.499 -score FROM_SUSPICIOUS_NTLD_FP 1.999 1.999 1.999 1.999 -score FSL_BULK_SIG 0.001 0.001 0.001 0.001 -score FSL_CTYPE_WIN1251 0.001 0.001 0.001 0.001 -score FSL_NEW_HELO_USER 0.001 0.001 0.001 0.001 -score FUZZY_AMAZON 0.001 0.001 0.001 0.001 -score FUZZY_BITCOIN 0.001 0.001 0.001 0.001 -score FUZZY_PORN 0.269 0.001 0.269 0.001 -score FUZZY_WALLET 1.799 0.001 1.799 0.001 -score GAPPY_SALES_LEADS_FREEM 1.000 1.000 1.000 1.000 -score GB_BITCOIN_CP 1.004 2.910 1.004 2.910 -score GB_BITCOIN_NH 0.965 0.737 0.965 0.737 -score GB_CUSTOM_HTM_URI 1.499 0.490 1.499 0.490 -score GB_FAKE_RF_SHORT 1.061 1.460 1.061 1.460 -score GB_FORGED_MUA_POSTFIX 1.000 1.000 1.000 1.000 -score GB_FREEMAIL_DISPTO 0.499 0.500 0.499 0.500 -score GB_FREEMAIL_DISPTO_NOTFREEM 0.500 0.500 0.500 0.500 -score GB_GOOGLE_OBFUR 0.750 0.750 0.750 0.750 -score GB_HASHBL_BTC 0.001 0.001 0.001 0.001 -score GB_STORAGE_GOOGLE_EMAIL 1.000 1.000 1.000 1.000 -score GB_URI_FLEEK_STO_HTM 0.999 0.999 0.999 0.999 -score GOOGLE_DOCS_PHISH 1.000 1.000 1.000 1.000 -score GOOGLE_DOCS_PHISH_MANY 1.000 1.000 1.000 1.000 -score GOOGLE_DOC_SUSP 1.000 1.000 1.000 1.000 -score GOOGLE_DRIVE_REPLY_BAD_NTLD 1.000 1.000 1.000 1.000 -score GOOG_MALWARE_DNLD 1.000 1.000 1.000 1.000 -score GOOG_REDIR_HTML_ONLY 2.000 1.999 2.000 1.999 -score GOOG_REDIR_NORDNS 2.499 2.549 2.499 2.549 -score GOOG_STO_EMAIL_PHISH 1.000 1.000 1.000 1.000 -score GOOG_STO_HTML_PHISH 1.000 1.000 1.000 1.000 -score GOOG_STO_HTML_PHISH_MANY 1.000 1.000 1.000 1.000 -score GOOG_STO_IMG_HTML 1.000 1.000 1.000 1.000 -score GOOG_STO_IMG_NOHTML 2.499 2.499 2.499 2.499 -score GOOG_STO_NOIMG_HTML 2.999 2.891 2.999 2.891 -score HAS_X_NO_RELAY 1.000 1.000 1.000 1.000 -score HAS_X_OUTGOING_SPAM_STAT 0.503 0.728 0.503 0.728 -score HDRS_LCASE_IMGONLY 0.099 0.100 0.099 0.100 -score HDRS_MISSP 2.500 2.499 2.500 2.499 -score HDR_ORDER_FTSDMCXX_DIRECT 0.001 0.001 0.001 0.001 -score HDR_ORDER_FTSDMCXX_NORDNS 0.001 0.001 0.001 0.001 -score HEADER_FROM_DIFFERENT_DOMAINS 0.250 0.249 0.250 0.249 -score HELO_NO_DOMAIN 0.001 0.001 0.001 0.001 -score HEXHASH_WORD 1.000 1.000 1.000 1.000 -score HK_CTE_RAW 1.000 1.000 1.000 1.000 -score HK_LOTTO 0.626 0.001 0.626 0.001 -score HK_NAME_MR_MRS 1.000 0.999 1.000 0.999 -score HK_RANDOM_ENVFROM 0.999 0.999 0.999 0.999 -score HK_RANDOM_FROM 0.999 0.999 0.999 0.999 -score HK_RANDOM_REPLYTO 0.999 0.999 0.999 0.999 -score HK_RCVD_IP_MULTICAST 1.000 1.000 1.000 1.000 -score HK_SCAM 1.999 1.999 1.999 1.999 -score HOSTED_IMG_DIRECT_MX 0.001 0.289 0.001 0.289 -score HOSTED_IMG_DQ_UNSUB 1.000 1.000 1.000 1.000 -score HOSTED_IMG_FREEM 3.499 3.464 3.499 3.464 -score HOSTED_IMG_MULTI 1.000 1.000 1.000 1.000 -score HOSTED_IMG_MULTI_PUB_01 2.999 2.999 2.999 2.999 -score HTML_ENTITY_ASCII 2.999 2.999 2.999 2.999 -score HTML_ENTITY_ASCII_TINY 1.000 1.000 1.000 1.000 -score HTML_FONT_TINY_NORDNS 1.886 1.085 1.886 1.085 -score HTML_OFF_PAGE 2.601 0.977 2.601 0.977 -score HTML_SHRT_CMNT_OBFU_MANY 1.000 1.000 1.000 1.000 -score HTML_SINGLET_MANY 2.499 1.000 2.499 1.000 -score HTML_TAG_BALANCE_CENTER 2.599 2.816 2.599 2.816 -score HTML_TEXT_INVISIBLE_FONT 1.924 0.609 1.924 0.609 -score HTML_TEXT_INVISIBLE_STYLE 0.472 1.312 0.472 1.312 -score IMG_ONLY_FM_DOM_INFO 1.000 1.000 1.000 1.000 -score JH_SPAMMY_HEADERS 3.499 3.499 3.499 3.499 -score JH_SPAMMY_PATTERN01 1.000 1.000 1.000 1.000 -score JH_SPAMMY_PATTERN02 1.000 1.000 1.000 1.000 -score KHOP_HELO_FCRDNS 0.399 0.001 0.399 0.001 -score KHOP_JS_OBFUSCATION 3.099 0.001 3.099 0.001 -score LINKEDIN_IMG_NOT_RCVD_LNKN 1.000 1.000 1.000 1.000 -score LIST_PRTL_PUMPDUMP 1.000 1.000 1.000 1.000 -score LIST_PRTL_SAME_USER 1.000 1.000 1.000 1.000 -score LONGLN_LOW_CONTRAST 0.123 1.329 0.123 1.329 -score LONG_HEX_URI 2.679 1.617 2.679 1.617 -score LONG_IMG_URI 2.599 0.001 2.599 0.001 -score LONG_INVISIBLE_TEXT 2.999 2.364 2.999 2.364 -score LOTS_OF_MONEY 0.010 0.009 0.010 0.009 -score LOTTO_AGENT 1.000 1.499 1.000 1.499 -score LOTTO_DEPT 0.754 1.096 0.754 1.096 -score LUCRATIVE 1.000 1.000 1.000 1.000 -score MALF_HTML_B64 1.000 1.000 1.000 1.000 -score MALWARE_NORDNS 0.001 0.616 0.001 0.616 -score MALWARE_PASSWORD 1.000 1.000 1.000 1.000 -score MAY_BE_FORGED 1.599 0.001 1.599 0.001 -score MILLION_HUNDRED 0.440 0.391 0.440 0.391 -score MILLION_USD 1.307 0.194 1.307 0.194 -score MIMEOLE_DIRECT_TO_MX 0.001 0.001 0.001 0.001 -score MIME_NO_TEXT 1.000 1.000 1.000 1.000 -score MIXED_AREA_CASE 1.000 1.000 1.000 1.000 -score MIXED_CENTER_CASE 1.000 1.000 1.000 1.000 -score MIXED_ES 2.199 2.399 2.199 2.399 -score MIXED_FONT_CASE 1.000 1.000 1.000 1.000 -score MIXED_HREF_CASE 1.000 1.000 1.000 1.000 -score MIXED_IMG_CASE 1.957 2.999 1.957 2.999 -score MONERO_DEADLINE 1.000 1.000 1.000 1.000 -score MONERO_EXTORT_01 1.000 1.000 1.000 1.000 -score MONERO_MALWARE 1.000 1.000 1.000 1.000 -score MONERO_PAY_ME 1.000 1.000 1.000 1.000 -score MONEY_ATM_CARD 0.560 1.599 0.560 1.599 -score MONEY_FORM 0.001 0.001 0.001 0.001 -score MONEY_FORM_SHORT 2.499 0.001 2.499 0.001 -score MONEY_FRAUD_3 2.499 2.499 2.499 2.499 -score MONEY_FRAUD_5 0.001 0.001 0.001 0.001 -score MONEY_FRAUD_8 0.001 0.001 0.001 0.001 -score MONEY_FREEMAIL_REPTO 2.999 1.155 2.999 1.155 -score MONEY_FROM_41 1.000 1.000 1.000 1.000 -score MONEY_FROM_MISSP 0.001 0.001 0.001 0.001 -score MSGID_DOLLARS_URI_IMG 1.000 1.000 1.000 1.000 -score MSGID_HDR_MALF 1.000 1.000 1.000 1.000 -score MSMAIL_PRI_ABNORMAL 1.499 1.499 1.499 1.499 -score MSM_PRIO_REPTO 1.000 1.000 1.000 1.000 -score NAME_EMAIL_DIFF 1.727 0.001 1.727 0.001 -score NA_DOLLARS 1.499 1.499 1.499 1.499 -score NEWEGG_IMG_NOT_RCVD_NEGG 1.000 1.000 1.000 1.000 -score NEW_PRODUCTS 1.000 1.000 1.000 1.000 -score NICE_REPLY_A -0.438 -0.001 -0.438 -0.001 -score NORDNS_LOW_CONTRAST 0.001 0.770 0.001 0.770 -score NO_FM_NAME_IP_HOSTN 0.001 0.001 0.001 0.001 -score NSL_RCVD_FROM_USER 0.001 0.001 0.001 0.001 -score NSL_RCVD_HELO_USER 0.001 0.001 0.001 0.001 -score NUMBERONLY_BITCOIN_EXP 1.735 1.787 1.735 1.787 -score OBFU_BITCOIN 0.001 0.001 0.001 0.001 -score OBFU_TEXT_ATTACH 1.499 1.444 1.499 1.444 -score ODD_FREEM_REPTO 2.999 1.845 2.999 1.845 -score PDS_BAD_THREAD_QP_64 0.999 0.999 0.999 0.999 -score PDS_BTC_ID 0.499 0.499 0.499 0.499 -score PDS_BTC_MSGID 0.302 0.001 0.302 0.001 -score PDS_BTC_NTLD 1.000 1.000 1.000 1.000 -score PDS_DBL_URL_TNB_RUNON 1.999 1.000 1.999 1.000 -score PDS_FROM_2_EMAILS 0.714 2.460 0.714 2.460 -score PDS_HELO_SPF_FAIL 0.001 1.000 0.001 1.000 -score PDS_NAKED_TO_NUMERO 1.999 2.000 1.999 2.000 -score PDS_NO_FULL_NAME_SPOOFED_URL 0.750 0.750 0.750 0.750 -score PDS_RDNS_DYNAMIC_FP 0.001 0.001 0.001 0.001 -score PDS_SHORT_SPOOFED_URL 1.999 1.999 1.999 1.999 -score PDS_TINYSUBJ_URISHRT 1.000 1.000 1.000 1.000 -score PDS_TONAME_EQ_TOLOCAL_FREEM_FORGE 1.000 1.000 1.000 1.000 -score PHISH_AZURE_CLOUDAPP 3.500 3.500 3.500 3.500 -score PHISH_FBASEAPP 1.000 1.000 1.000 1.000 -score PHP_NOVER_MUA 1.000 1.000 1.000 1.000 -score PHP_ORIG_SCRIPT 2.001 2.036 2.001 2.036 -score PHP_SCRIPT 2.499 2.499 2.499 2.499 -score PHP_SCRIPT_MUA 1.000 1.000 1.000 1.000 -score PP_MIME_FAKE_ASCII_TEXT 0.999 0.001 0.999 0.001 -score PP_TOO_MUCH_UNICODE02 0.500 0.500 0.500 0.500 -score PP_TOO_MUCH_UNICODE05 1.000 1.000 1.000 1.000 -score PUMPDUMP 1.000 1.000 1.000 1.000 -score PUMPDUMP_MULTI 1.000 1.000 1.000 1.000 -score RAND_HEADER_LIST_SPOOF 1.000 1.000 1.000 1.000 -score RAND_HEADER_MANY 1.000 1.000 1.000 1.000 -score RAND_MKTG_HEADER 1.999 1.999 1.999 1.999 -score RATWARE_NO_RDNS 1.864 0.001 1.864 0.001 -score RCVD_DOTEDU_SHORT 1.000 1.000 1.000 1.000 -score RCVD_DOTEDU_SUSP_URI 1.000 1.000 1.000 1.000 -score RCVD_IN_MSPIKE_BL 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_H2 0.001 -0.001 0.001 -0.001 -score RCVD_IN_MSPIKE_H3 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_H4 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_H5 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_L2 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_L3 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_L4 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_L5 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_WL 0.001 0.001 0.001 0.001 -score RCVD_IN_MSPIKE_ZBI 0.001 0.001 0.001 0.001 -score RDNS_NUM_TLD_ATCHNX 1.000 1.000 1.000 1.000 -score RDNS_NUM_TLD_XM 2.681 2.999 2.681 2.999 -score READY_TO_SHIP 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_AOL 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_AOL_LOOSE 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_CNS 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_GM 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_GM_LOOSE 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_HM 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_OL 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_PM 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_QQ 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_YH 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_YH_LOOSE 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_YJ 1.000 1.000 1.000 1.000 -score REPTO_419_FRAUD_YN 1.000 1.000 1.000 1.000 -score REPTO_INFONUMSCOM 1.000 1.000 1.000 1.000 -score SCC_CANSPAM_1 2.300 0.001 2.300 0.001 -score SCC_CANSPAM_2 2.299 2.599 2.299 2.599 -score SCC_ISEMM_LID_1 1.000 1.000 1.000 1.000 -score SCC_ISEMM_LID_1A 1.000 1.000 1.000 1.000 -score SCC_ISEMM_LID_1B 1.499 1.499 1.499 1.499 -score SENDGRID_REDIR 1.499 1.068 1.499 1.068 -score SENDGRID_REDIR_PHISH 1.000 1.000 1.000 1.000 -score SEO_SUSP_NTLD 1.000 1.000 1.000 1.000 -score SERGIO_SUBJECT_VIAGRA01 2.699 2.656 2.699 2.656 -score SHOPIFY_IMG_NOT_RCVD_SFY 2.499 2.499 2.499 2.499 -score SHORTENER_SHORT_IMG 0.001 1.002 0.001 1.002 -score SHORT_IMG_SUSP_NTLD 1.000 1.000 1.000 1.000 -score SHORT_SHORTNER 1.999 1.999 1.999 1.999 -score SPOOFED_FREEMAIL 0.001 0.001 0.001 0.001 -score SPOOFED_FREEMAIL_NO_RDNS 0.001 0.001 0.001 0.001 -score SPOOFED_FREEM_REPTO 0.001 0.001 0.001 0.001 -score SPOOFED_FREEM_REPTO_CHN 0.001 1.000 0.001 1.000 -score SPOOFED_FREEM_REPTO_RUS 0.001 1.000 0.001 1.000 -score SPOOF_GMAIL_MID 1.499 0.001 1.499 0.001 -score STATIC_XPRIO_OLE 0.001 0.001 0.001 0.001 -score STOCK_TIP 1.000 1.000 1.000 1.000 -score STOX_BOUND_090909_B 0.001 0.001 0.001 0.001 -score SUBJ_ATTENTION 0.128 0.500 0.128 0.500 -score SUBJ_BRKN_WORDNUMS 1.000 1.000 1.000 1.000 -score SURBL_BLOCKED 0.001 0.001 0.001 0.001 -score SUSP_UTF8_WORD_SUBJ 1.999 1.970 1.999 1.970 -score SYSADMIN 1.000 1.000 1.000 1.000 -score TAGSTAT_IMG_NOT_RCVD_TGST 1.000 1.000 1.000 1.000 -score TARINGANET_IMG_NOT_RCVD_TN 1.000 1.000 1.000 1.000 -score THIS_AD 2.099 1.815 2.099 1.815 -score THIS_IS_ADV_SUSP_NTLD 1.000 1.000 1.000 1.000 -score TONLINE_FAKE_DKIM 1.000 1.000 1.000 1.000 -score TO_EQ_FM_DIRECT_MX 1.000 1.000 1.000 1.000 -score TO_EQ_FM_DOM_SPF_FAIL 0.001 0.001 0.001 0.001 -score TO_EQ_FM_SPF_FAIL 0.001 0.001 0.001 0.001 -score TO_IN_SUBJ 0.100 0.100 0.100 0.100 -score TO_NAME_SUBJ_NO_RDNS 0.338 1.000 0.338 1.000 -score TO_NO_BRKTS_FROM_MSSP 2.499 2.499 2.499 2.499 -score TO_NO_BRKTS_HTML_IMG 1.999 1.999 1.999 1.999 -score TO_NO_BRKTS_HTML_ONLY 1.999 1.999 1.999 1.999 -score TO_NO_BRKTS_MSFT 0.001 0.001 0.001 0.001 -score TO_NO_BRKTS_NORDNS_HTML 1.999 1.597 1.999 1.597 -score TO_NO_BRKTS_PCNT 2.500 2.499 2.500 2.499 -score TVD_PH_BODY_META 2.099 2.299 2.099 2.299 -score TVD_RCVD_SPACE_BRACKET 2.554 1.427 2.554 1.427 -score TVD_SPACE_ENCODED 1.821 0.001 1.821 0.001 -score TVD_SPACE_RATIO_MINFP 0.238 0.001 0.238 0.001 -score TW_GIBBERISH_MANY 1.000 1.000 1.000 1.000 -score UC_GIBBERISH_OBFU 1.000 1.000 1.000 1.000 -score UNDISC_FREEM 2.699 2.700 2.699 2.700 -score UNDISC_MONEY 2.899 3.099 2.899 3.099 -score UNICODE_OBFU_ASC 2.499 2.499 2.499 2.499 -score UNICODE_OBFU_ZW 1.000 1.000 1.000 1.000 -score UNSUB_GOOG_FORM 1.000 1.000 1.000 1.000 -score URI_ADOBESPARK 1.000 1.000 1.000 1.000 -score URI_AZURE_CLOUDAPP 1.000 1.000 1.000 1.000 -score URI_DASHGOVEDU 1.000 1.000 1.000 1.000 -score URI_DATA 1.000 1.000 1.000 1.000 -score URI_DOTEDU 1.999 1.278 1.999 1.278 -score URI_DOTEDU_ENTITY 1.000 1.000 1.000 1.000 -score URI_FIREBASEAPP 1.000 1.000 1.000 1.000 -score URI_GOOGLE_PROXY 1.999 1.999 1.999 1.999 -score URI_GOOG_STO_SPAMMY 3.000 3.000 3.000 3.000 -score URI_HEX_IP 1.000 1.000 1.000 1.000 -score URI_IMG_WP_REDIR 1.000 1.000 1.000 1.000 -score URI_LONG_REPEAT 1.000 1.000 1.000 1.000 -score URI_ONLY_MSGID_MALF 0.001 1.000 0.001 1.000 -score URI_OPTOUT_3LD 1.000 1.000 1.000 1.000 -score URI_PHISH 3.999 3.695 3.999 3.695 -score URI_PHP_REDIR 1.000 1.000 1.000 1.000 -score URI_TRY_3LD 1.950 0.956 1.950 0.956 -score URI_TRY_USME 1.000 1.000 1.000 1.000 -score URI_WPADMIN 1.685 2.099 1.685 2.099 -score URI_WP_DIRINDEX 1.000 1.000 1.000 1.000 -score URI_WP_HACKED 1.685 3.499 1.685 3.499 -score URI_WP_HACKED_2 2.499 2.499 2.499 2.499 -score USB_DRIVES 1.000 1.000 1.000 1.000 -score VFY_ACCT_NORDNS 2.633 2.551 2.633 2.551 -score VPS_NO_NTLD 1.000 1.000 1.000 1.000 -score WALMART_IMG_NOT_RCVD_WAL 1.000 1.000 1.000 1.000 -score WORD_INVIS 0.972 0.001 0.972 0.001 -score WORD_INVIS_MANY 2.999 2.999 2.999 2.999 -score XFER_LOTSA_MONEY 0.999 0.999 0.999 0.999 -score XM_DIGITS_ONLY 1.000 1.000 1.000 1.000 -score XM_RANDOM 1.665 0.256 1.665 0.256 -score XPRIO 0.617 0.001 0.617 0.001 -score XPRIO_SHORT_SUBJ 1.133 2.172 1.133 2.172 -score XPRIO_URL_SHORTNER 0.429 0.613 0.429 0.613 -score YOUR_DELIVERY_ADDRESS 1.000 1.000 1.000 1.000 diff --git a/resources/spamassassin/73_sandbox_manual_scores.cf b/resources/spamassassin/73_sandbox_manual_scores.cf deleted file mode 100644 index f424c605..00000000 --- a/resources/spamassassin/73_sandbox_manual_scores.cf +++ /dev/null @@ -1,121 +0,0 @@ -# SpamAssassin rules file -# -# Manual override of the automatically-generated scores -# for automatically-published sandbox rules -# -# <@LICENSE> -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to you under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# -########################################################################### - -require_version @@VERSION@@ - -# jhardin -# things depend on these -# score as informative just for the hits header -score LOTS_OF_MONEY 0.001 -score FILL_THIS_FORM 0.001 - -# jhardin -# reevolved Advance Fee rules -# scores are cumulative (i.e. 3 hits 2, 4 hits 3 and 2) -# Commented out if GA is scoring reasonably -#score ADVANCE_FEE_2_NEW_MONEY 0.50 -#score ADVANCE_FEE_2_NEW_FORM 0.75 -#score ADVANCE_FEE_3_NEW 0.50 -#score ADVANCE_FEE_3_NEW_MONEY 1.00 -#score ADVANCE_FEE_3_NEW_FORM 1.00 -#score ADVANCE_FEE_4_NEW 1.00 -#score ADVANCE_FEE_5_NEW 1.50 -score ADVANCE_FEE_5_NEW_MONEY 3.00 - -# jhardin -# metas using Advance Fee component rules -# Commented out if GA is scoring reasonably -#score FORM_FRAUD_3 0.50 -#score FORM_FRAUD_5 0.50 -#score MONEY_FRAUD_3 1.00 -#score MONEY_FRAUD_5 0.50 -#score MONEY_FRAUD_8 0.50 - -# jhardin -# GA scores this unreasonably high, and -# the fact that this is defined in an #ifplugin -# appears to be preventing score limiting from working -score FILL_THIS_FORM_LONG 2.00 - -# jhardin -# misc rules -# Commented out if GA is scoring reasonably -#score FROM_MISSP_MSFT 0.50 -#score TO_NO_BRKTS_DYNIP 0.50 -#score LOTTO_AGENT 0.50 - -# jhardin -# 1.000 S/O, hits only <= 6 points, but GA is not publishing it! -# perhaps because very few examples in spam corpus -# 12/24/12 GA likes it now -#score GOOGLE_DOCS_PHISH 3.00 -# similar: .990 S/O, hits primarily spam <= 5 points -# 01/07/13 GA likes it now -#score EMAIL_URI_PHISH 2.50 -# Reliable but not widespread (low corpus count, ahead of the curve?), boost the score -score PHISH_AZURE_CLOUDAPP 3.50 -score URI_GOOG_STO_SPAMMY 3.50 - -# jhardin -# double-extension file attachments, low corpus count -score PHISH_ATTACH 3.50 -score MALW_ATTACH 3.50 - -# hege -# FPs reported [bug 6417], GA assigning 3+ points -# reduce score until that's resolved -# score HK_FAKENAME_MICROSOFT 2.50 -# RULE DISABLED IN 20_hk.cf - -# jhardin for mmartinec -# Lots of hate; score as informative hammy, may override locally -score RP_MATCHES_RCVD -0.001 - -# until rule or rescoring issues sorted, hits 20%+ ham -# too problematic, disabled entirely -#score STYLE_GIBBERISH 0.1 - -# jhardin -# Limit some network scores until rule changes can be evaluated by weekly net masscheck -# Dangit, relative scores are broken - see bug#7721 -#score FROM_IN_TO_AND_SUBJ (0) 0.001 (0) 0.001 -#score OBFU_TEXT_ATTACH (0) 0.001 (0) 0.001 -#score MIME_NO_TEXT (0) 0.001 (0) 0.001 -#score AD_PREFS (0) 0.001 (0) 0.001 -score AD_PREFS 0.250 -#score URI_WP_HACKED_2 (0) 0.001 (0) 0.001 -#score STYLE_GIBBERISH (0) 0.001 (0) 0.001 -#score UC_GIBBERISH_OBFU (0) 0.001 (0) 0.001 -#score LUCRATIVE (0) 0.001 (0) 0.001 -#score HEXHASH_WORD (0) 0.001 (0) 0.001 -#score FROM_WORDY (0) 0.001 (0) 0.001 -#score AC_HTML_NONSENSE_TAGS (0) 0.001 (0) 0.001 -#score LONG_HEX_URI (0) 0.001 (0) 0.001 -#score FROM_PAYPAL_SPOOF (0) 0.001 (0) 0.001 - - -# jhardin -# Don't joe-job a SA dev's wife -score ADULT_DATING_COMPANY 20.000 - diff --git a/resources/spamassassin/Mail-SpamAssassin-rules-4.0.0.r1905950.tgz b/resources/spamassassin/Mail-SpamAssassin-rules-4.0.0.r1905950.tgz deleted file mode 100644 index 69e2e64212a6cf797f3086c5559fcd38315d9536..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 355737 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℞z&|l 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ξsJoa2ub2l3K>Jg#~yMdtrUMK`TjDOXrZ{!c?s?r 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