$NetBSD: patch-RequiredFrom,v 1.2 2021/05/27 16:52:00 manu Exp $

Add RequiredFrom option to reject messages that lack a From header
from which a valid domain can be extracted

Submitted upstream as 
https://github.com/trusteddomainproject/OpenDMARC/pull/147

--- ./opendmarc/opendmarc.c.orig	2021-04-30 18:34:43.000000000 +0200
+++ ./opendmarc/opendmarc.c	2021-05-27 10:20:33.880652427 +0200
@@ -163,8 +163,9 @@
 /* DMARCF_CONFIG -- configuration object */
 struct dmarcf_config
 {
 	_Bool			conf_reqhdrs;
+	_Bool			conf_reqfrom;
 	_Bool			conf_afrf;
 	_Bool			conf_afrfnone;
 	_Bool			conf_rejectfail;
 	_Bool			conf_dolog;
@@ -1422,8 +1423,12 @@
 		(void) config_get(data, "RequiredHeaders",
 		                  &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);
 
@@ -2453,13 +2458,17 @@
 	{
 		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: addresses */
 	memset(addrbuf, '\0', sizeof addrbuf);
@@ -2495,13 +2504,13 @@
 	{
 		if (conf->conf_dolog)
 		{
 			syslog(LOG_ERR,
-			       "%s: unable to parse From header field",
-			       dfc->mctx_jobid);
+			       "%s: unable to parse From header field \"%s\"",
+			       dfc->mctx_jobid, from->hdr_value);
 		}
 
-		if (conf->conf_reqhdrs)
+		if (conf->conf_reqhdrs || conf->conf_reqfrom) 
 			return SMFIS_REJECT;
 		else
 			return SMFIS_ACCEPT;
 	}
--- ./opendmarc/opendmarc.conf.5.in.orig	2021-04-30 18:34:43.000000000 +0200
+++ ./opendmarc/opendmarc.conf.5.in	2021-05-27 10:20:33.881043733 +0200
@@ -287,8 +287,16 @@
 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
 connections from
 .I sendmail(8)
--- ./opendmarc/opendmarc-config.h.orig	2021-04-30 18:34:43.000000000 +0200
+++ ./opendmarc/opendmarc-config.h	2021-05-27 10:23:12.866999966 +0200
@@ -44,8 +44,9 @@
 	{ "PidFile",			CONFIG_TYPE_STRING,	FALSE },
 	{ "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 },
 	{ "RejectMultiValueFrom",	CONFIG_TYPE_BOOLEAN,	FALSE },
 	{ "ReportCommand",		CONFIG_TYPE_STRING,	FALSE },
 	{ "Socket",			CONFIG_TYPE_STRING,	FALSE },
--- ./opendmarc/opendmarc.conf.sample.orig	2021-04-30 18:34:43.000000000 +0200
+++ ./opendmarc/opendmarc.conf.sample	2021-05-27 10:20:33.882715995 +0200
@@ -343,8 +343,17 @@
 ##  rejected.
 #
 # 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)
 ##
 ##  Specifies the socket that should be established by the filter to receive
