Skip to content

Commit

Permalink
Add RequiredFrom option to opendmarc.conf
Browse files Browse the repository at this point in the history
If RequiredFrom is set, opendmarc will reject messages that lack
a From header from which a valid domain can be extracted. This
is a subset of the full RFC5322 requirements enforced by the
RequiredHeaders option.

While non RFC5322-compliant messages are too common to make
RequiredHeaders always usable, the check on the From header
remains especially valuable. It makes sure forged domain messages
cannot evade the filter by just omitting the From header and relying
on the MTA to fill it by a copy from the enveloppe header.
  • Loading branch information
manu0401 committed Mar 29, 2021
1 parent b0d6408 commit 41f86c4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
1 change: 1 addition & 0 deletions opendmarc/opendmarc-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct configdef dmarcf_config[] =
{ "PublicSuffixList", CONFIG_TYPE_STRING, FALSE },
{ "RecordAllMessages", CONFIG_TYPE_BOOLEAN, FALSE },
{ "RequiredHeaders", CONFIG_TYPE_BOOLEAN, FALSE },
{ "RequiredFrom", CONFIG_TYPE_BOOLEAN, FALSE },
{ "RejectFailures", CONFIG_TYPE_BOOLEAN, FALSE },
{ "ReportCommand", CONFIG_TYPE_STRING, FALSE },
{ "Socket", CONFIG_TYPE_STRING, FALSE },
Expand Down
17 changes: 13 additions & 4 deletions opendmarc/opendmarc.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ typedef struct dmarcf_connctx * DMARCF_CONNCTX;
struct dmarcf_config
{
_Bool conf_reqhdrs;
_Bool conf_reqfrom;
_Bool conf_afrf;
_Bool conf_afrfnone;
_Bool conf_rejectfail;
Expand Down Expand Up @@ -1269,6 +1270,10 @@ dmarcf_config_load(struct config *data, struct dmarcf_config *conf,
&conf->conf_reqhdrs,
sizeof conf->conf_reqhdrs);

(void) config_get(data, "RequiredFrom",
&conf->conf_reqfrom,
sizeof conf->conf_reqfrom);

(void) config_get(data, "FailureReports",
&conf->conf_afrf,
sizeof conf->conf_afrf);
Expand Down Expand Up @@ -2152,11 +2157,15 @@ mlfi_eom(SMFICTX *ctx)
if (conf->conf_dolog)
{
syslog(LOG_INFO,
"%s: RFC5322 requirement error: missing From field; accepting",
dfc->mctx_jobid);
"%s: RFC5322 requirement error: missing From field; %s",
dfc->mctx_jobid,
conf->conf_reqfrom ? "reject" : "accepting");
}

return SMFIS_ACCEPT;
if (conf->conf_reqfrom)
return SMFIS_REJECT;
else
return SMFIS_ACCEPT;
}

/* extract From: domain */
Expand All @@ -2172,7 +2181,7 @@ mlfi_eom(SMFICTX *ctx)
dfc->mctx_jobid);
}

if (conf->conf_reqhdrs)
if (conf->conf_reqhdrs || conf->conf_reqfrom)
return SMFIS_REJECT;
else
return SMFIS_ACCEPT;
Expand Down
8 changes: 8 additions & 0 deletions opendmarc/opendmarc.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,14 @@ header field count restrictions laid out in RFC5322, Section 3.6. Messages
failing this test are rejected without further processing. A From:
field from which no domain name could be extracted will also be rejected.

.TP
.I RequiredFrom (Boolean)
If set, the filter will reject without further processing messages that lack a
From: field from which a domain name could be extracted. This options is
without effect if
.I RequiredHeaders
is set to "true".

.TP
.I Socket (string)
Specifies the socket that should be established by the filter to receive
Expand Down
9 changes: 9 additions & 0 deletions opendmarc/opendmarc.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@
#
# RequiredHeaders false

## RequiredFrom { true | false }
## default "false"
##
## If set, the filter will reject without further processing messages that
## lack a From: field from which a domain name could be extracted. This
## options is without effect if RequiredHeaders is set to "true".
#
# RequiredFrom false

## Socket socketspec
## default (none)
##
Expand Down

0 comments on commit 41f86c4

Please sign in to comment.