aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2024-07-18 19:42:22 +0600
committerGitHub <noreply@github.com>2024-07-18 19:42:22 +0600
commit658a9d27dd89f171379b75460481d7e3f3f249e9 (patch)
tree9cdfb85642f937f6a84569d152523d69483af855
parentcc32ef81407e0b43751d914b19ea1f6da07781b4 (diff)
parent8b4dee26282d4899d78beeb2521dc32d371fca0b (diff)
downloadrspamd-658a9d27dd89f171379b75460481d7e3f3f249e9.tar.gz
rspamd-658a9d27dd89f171379b75460481d7e3f3f249e9.zip
Merge pull request #5059 from rspamd/vstakhov-spf-plusall
[Feature] Treat SPF +all in a special way
-rw-r--r--conf/scores.d/policies_group.conf5
-rw-r--r--src/libserver/spf.c5
-rw-r--r--src/libserver/spf.h2
-rw-r--r--src/lua/lua_spf.c7
-rw-r--r--src/plugins/lua/spf.lua3
-rw-r--r--test/functional/cases/001_merged/117_spf.robot6
-rw-r--r--test/functional/configs/merged-local.conf5
7 files changed, 32 insertions, 1 deletions
diff --git a/conf/scores.d/policies_group.conf b/conf/scores.d/policies_group.conf
index 4a8bdb6b7..712c61523 100644
--- a/conf/scores.d/policies_group.conf
+++ b/conf/scores.d/policies_group.conf
@@ -55,6 +55,11 @@ symbols = {
description = "SPF record is malformed or persistent DNS error";
groups = ["spf"];
}
+ "R_SPF_PLUSALL" {
+ weight = 4.0;
+ description = "SPF record allows to send from any IP";
+ groups = ["spf"];
+ }
# DKIM
"R_DKIM_REJECT" {
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index 32c020bf3..562222042 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -451,6 +451,9 @@ rspamd_spf_process_reference(struct spf_resolved *target,
target->flags |= RSPAMD_SPF_RESOLVED_NA;
continue;
}
+ if (cur->flags & RSPAMD_SPF_FLAG_PLUSALL) {
+ target->flags |= RSPAMD_SPF_RESOLVED_PLUSALL;
+ }
if (cur->flags & RSPAMD_SPF_FLAG_INVALID) {
/* Ignore invalid elements */
continue;
@@ -1418,7 +1421,7 @@ parse_spf_all(struct spf_record *rec, struct spf_addr *addr)
/* Disallow +all */
if (addr->mech == SPF_PASS) {
- addr->flags |= RSPAMD_SPF_FLAG_INVALID;
+ addr->flags |= RSPAMD_SPF_FLAG_PLUSALL;
msg_notice_spf("domain %s allows any SPF (+all), ignore SPF record completely",
rec->sender_domain);
}
diff --git a/src/libserver/spf.h b/src/libserver/spf.h
index cc0ee4c05..b89dc4d0e 100644
--- a/src/libserver/spf.h
+++ b/src/libserver/spf.h
@@ -77,6 +77,7 @@ typedef enum spf_action_e {
#define RSPAMD_SPF_FLAG_PERMFAIL (1u << 10u)
#define RSPAMD_SPF_FLAG_RESOLVED (1u << 11u)
#define RSPAMD_SPF_FLAG_CACHED (1u << 12u)
+#define RSPAMD_SPF_FLAG_PLUSALL (1u << 13u)
/** Default SPF limits for avoiding abuse **/
#define SPF_MAX_NESTING 10
@@ -104,6 +105,7 @@ enum rspamd_spf_resolved_flags {
RSPAMD_SPF_RESOLVED_TEMP_FAILED = (1u << 0u),
RSPAMD_SPF_RESOLVED_PERM_FAILED = (1u << 1u),
RSPAMD_SPF_RESOLVED_NA = (1u << 2u),
+ RSPAMD_SPF_RESOLVED_PLUSALL = (1u << 3u),
};
struct spf_resolved {
diff --git a/src/lua/lua_spf.c b/src/lua/lua_spf.c
index 46e72202f..850ce2120 100644
--- a/src/lua/lua_spf.c
+++ b/src/lua/lua_spf.c
@@ -89,6 +89,8 @@ lua_load_spf(lua_State *L)
lua_setfield(L, -2, "perm_fail");
lua_pushinteger(L, RSPAMD_SPF_FLAG_CACHED);
lua_setfield(L, -2, "cached");
+ lua_pushinteger(L, RSPAMD_SPF_RESOLVED_PLUSALL);
+ lua_setfield(L, -2, "plusall");
lua_setfield(L, -2, "flags");
@@ -368,6 +370,11 @@ spf_check_element(lua_State *L, struct spf_resolved *rec, struct spf_addr *addr,
lua_pushinteger(L, RSPAMD_SPF_RESOLVED_TEMP_FAILED);
lua_pushfstring(L, "%cany", spf_mech_char(addr->mech));
}
+ else if (rec->flags & RSPAMD_SPF_RESOLVED_PLUSALL) {
+ lua_pushboolean(L, false);
+ lua_pushinteger(L, RSPAMD_SPF_RESOLVED_PLUSALL);
+ lua_pushfstring(L, "%cany", spf_mech_char(addr->mech));
+ }
else {
lua_pushboolean(L, true);
lua_pushinteger(L, addr->mech);
diff --git a/src/plugins/lua/spf.lua b/src/plugins/lua/spf.lua
index 48f3c17be..356507250 100644
--- a/src/plugins/lua/spf.lua
+++ b/src/plugins/lua/spf.lua
@@ -56,6 +56,7 @@ local symbols = {
dnsfail = "R_SPF_DNSFAIL",
permfail = "R_SPF_PERMFAIL",
na = "R_SPF_NA",
+ plusall = "R_SPF_PLUSALL",
}
local default_config = {
@@ -118,6 +119,8 @@ local function spf_check_callback(task)
local function flag_to_symbol(fl)
if bit.band(fl, rspamd_spf.flags.temp_fail) ~= 0 then
return local_config.symbols.dnsfail
+ elseif bit.band(fl, rspamd_spf.flags.plusall) ~= 0 then
+ return local_config.symbols.plusall
elseif bit.band(fl, rspamd_spf.flags.perm_fail) ~= 0 then
return local_config.symbols.permfail
elseif bit.band(fl, rspamd_spf.flags.na) ~= 0 then
diff --git a/test/functional/cases/001_merged/117_spf.robot b/test/functional/cases/001_merged/117_spf.robot
index dda35f671..a8b35a8c9 100644
--- a/test/functional/cases/001_merged/117_spf.robot
+++ b/test/functional/cases/001_merged/117_spf.robot
@@ -155,3 +155,9 @@ SPF UPPERCASE
... IP=8.8.8.8 From=x@fail11.org.org.za
... Settings=${SETTINGS_SPF}
Expect Symbol R_SPF_ALLOW
+
+SPF PLUSALL
+ Scan File ${RSPAMD_TESTDIR}/messages/dmarc/bad_dkim1.eml
+ ... IP=8.8.8.8 From=x@plusall.com
+ ... Settings=${SETTINGS_SPF}
+ Expect Symbol R_SPF_PLUSALL
diff --git a/test/functional/configs/merged-local.conf b/test/functional/configs/merged-local.conf
index 75b9f0554..2d914b075 100644
--- a/test/functional/configs/merged-local.conf
+++ b/test/functional/configs/merged-local.conf
@@ -229,6 +229,11 @@ options = {
replies = ["v=spf1 -all"];
},
{
+ name = "plusall.com",
+ type = "txt";
+ replies = ["v=spf1 +all"];
+ },
+ {
name = "fail4.org.org.za",
type = "txt";
replies = ["v=spf1 redirect=asdfsfewewrredfs"];