Skip to content

Commit

Permalink
Merge pull request #42 from jcbf/jcbf/refuse-spf-none
Browse files Browse the repository at this point in the history
Configurable refuse when SPF is none
  • Loading branch information
jcbf committed Feb 8, 2018
2 parents e30dafc + 230d4e3 commit ba300b0
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions smf-spf-tests-refuse.conf
@@ -1,5 +1,6 @@
WhitelistIP 127.0.0.0/8
RefuseFail on # (on|off)
RefuseSPFnone on # (on|off)
SoftFail off # (on|off)
AcceptTempError off
TagSubject of # (on|off)
Expand Down
16 changes: 16 additions & 0 deletions smf-spf.c
Expand Up @@ -51,6 +51,7 @@
#define SYSLOG_FACILITY LOG_MAIL
#define SPF_TTL 3600
#define REFUSE_FAIL 1
#define REFUSE_NONE 0
#define SOFT_FAIL 0
#define ACCEPT_PERMERR 1
#define TAG_SUBJECT 1
Expand Down Expand Up @@ -133,6 +134,7 @@ typedef struct config {
STR *froms;
STR *tos;
int refuse_fail;
int refuse_none;
int soft_fail;
int accept_temperror;
int tag_subject;
Expand Down Expand Up @@ -372,6 +374,7 @@ static int load_config(void) {
conf.sendmail_socket = strdup(OCONN);
conf.syslog_facility = SYSLOG_FACILITY;
conf.refuse_fail = REFUSE_FAIL;
conf.refuse_none = REFUSE_NONE;
conf.soft_fail = SOFT_FAIL;
conf.accept_temperror = ACCEPT_PERMERR;
conf.tag_subject = TAG_SUBJECT;
Expand Down Expand Up @@ -469,6 +472,10 @@ static int load_config(void) {
conf.soft_fail = 1;
continue;
}
if (!strcasecmp(key, "refusespfnone") && !strcasecmp(val, "on")) {
conf.refuse_none = 1;
continue;
}
if (!strcasecmp(key, "refusefail") && !strcasecmp(val, "off")) {
conf.refuse_fail = 0;
continue;
Expand Down Expand Up @@ -774,6 +781,15 @@ static sfsistat smf_envfrom(SMFICTX *ctx, char **args) {
SPF_request_set_env_from(spf_request, context->sender);
if (SPF_request_query_mailfrom(spf_request, &spf_response)) {
syslog(LOG_INFO, "SPF none: ip=%s, fqdn=%s, helo=%s, from=%s", context->addr, context->fqdn, context->helo, context->from);
if (status == SPF_RESULT_NONE && conf.refuse_none && !strstr(context->from, "<>")) {
char reject[2 * MAXLINE];
snprintf(reject, sizeof(reject), "Sorry, we only accept mail from SPF enabled domains", context->sender);
if (spf_response) SPF_response_free(spf_response);
if (spf_request) SPF_request_free(spf_request);
if (spf_server) SPF_server_free(spf_server);
smfi_setreply(ctx, "550" , "5.7.1", reject);
return SMFIS_REJECT;
}
if (cache && conf.spf_ttl) {
mutex_lock(&cache_mutex);
cache_put(context->key, conf.spf_ttl, SPF_RESULT_NONE);
Expand Down
7 changes: 7 additions & 0 deletions smf-spf.conf
Expand Up @@ -36,6 +36,13 @@ WhitelistIP 192.168.0.0/16
#WhitelistTo @yourspamloverdomain.tld
#WhitelistTo spamlover@yourdomain.tld

# Refuse e-Mail messages at SPF None results
# On empty senders this restriction will not be applied
#
# Default: off
#
#RefuseSPFNone off # (on|off)

# Refuse e-Mail messages at SPF Fail results (RFC-4408)
#
# Default: on
Expand Down
36 changes: 36 additions & 0 deletions tests/04-fulltest-refusenone.lua
@@ -0,0 +1,36 @@
-- Copyright (c) 2009-2013, The Trusted Domain Project. All rights reserved.
mt.echo("SPF pass test")

-- try to start the filter
mt.startfilter("./smf-spf", "-f", "-c","./smf-spf-tests-refuse.conf")

-- try to connect to it
conn = mt.connect("inet:2424@127.0.0.1", 40, 0.25)
if conn == nil then
error("mt.connect() failed")
end

-- send connection information
-- mt.negotiate() is called implicitly
mt.macro(conn, SMFIC_CONNECT, "j", "mta.name.local")
if mt.conninfo(conn, "localhost", "195.22.26.194") ~= nil then
error("mt.conninfo() failed")
end
if mt.getreply(conn) ~= SMFIR_CONTINUE then
error("mt.conninfo() unexpected reply")
end

-- send envelope macros and sender data
-- mt.helo() is called implicitly
mt.macro(conn, SMFIC_MAIL, "i", "t-verify-spfnone")
if mt.mailfrom(conn, "<user@nospf.underspell.com>") ~= nil then
error("mt.mailfrom() failed")
end

if mt.getreply(conn) ~= SMFIR_REPLYCODE then
error("mt.mailfrom() unexpected reply")
end

print ("received SMFIR_REJECT ")

mt.disconnect(conn)

0 comments on commit ba300b0

Please sign in to comment.