summaryrefslogtreecommitdiffstats
path: root/network/opendmarc/patches/z04_moreHeadersFailureReportVsBeta1.patch
blob: 23dc08f467d5f2ce9c67b1fbbe46e58815d97a16 (plain)
--- a/opendmarc/opendmarc.c	2016-12-21 18:01:21.322036404 +0100
+++ b/opendmarc/opendmarc.c	2016-12-21 18:01:48.893181823 +0100
@@ -2057,6 +2057,7 @@
 	char *apolicy = NULL;
 	char *aresult = NULL;
 	char *adisposition = NULL;
+	char *deliveryresult = NULL;
 	char *hostname = NULL;
 	char *authservid = NULL;
 	char *spfaddr;
@@ -2774,6 +2775,154 @@
 	}
 
 	/*
+	**  Enact policy based on DMARC results.
+	*/
+
+	result = DMARC_RESULT_ACCEPT;
+
+	switch (policy)
+	{
+	  case DMARC_POLICY_ABSENT:		/* No DMARC record found */
+	  case DMARC_FROM_DOMAIN_ABSENT:	/* No From: domain */
+		aresult = "none";
+		ret = SMFIS_ACCEPT;
+		result = DMARC_RESULT_ACCEPT;
+		break;
+
+	  case DMARC_POLICY_NONE:		/* Alignment failed, but policy is none: */
+		aresult = "fail";		/* Accept and report */
+		ret = SMFIS_ACCEPT;
+		result = DMARC_RESULT_ACCEPT;
+		break;
+
+	  case DMARC_POLICY_PASS:		/* Explicit accept */
+		aresult = "pass";
+		ret = SMFIS_ACCEPT;
+		result = DMARC_RESULT_ACCEPT;
+		break;
+
+	  case DMARC_POLICY_REJECT:		/* Explicit reject */
+		aresult = "fail";
+
+		if (conf->conf_overridemlm != NULL &&
+		    (dmarcf_checkhost(cc->cctx_host, conf->conf_overridemlm) ||
+		    (dmarcf_checkip((struct sockaddr *)&cc->cctx_ip, conf->conf_overridemlm))))
+		{
+			if (conf->conf_dolog)
+			{
+				syslog(LOG_INFO, "%s: overriding policy for mail from %s: MLM",
+				       dfc->mctx_jobid, dfc->mctx_fromdomain);
+			}
+			ret = SMFIS_ACCEPT;
+			result = DMARC_RESULT_OVRD_MAILING_LIST;
+		}
+		else
+		{
+			if (conf->conf_rejectfail && random() % 100 < pct)
+			{
+				snprintf(replybuf, sizeof replybuf,
+					 "rejected by DMARC policy for %s", pdomain);
+
+				status = dmarcf_setreply(ctx, DMARC_REJECT_SMTP,
+							 DMARC_REJECT_ESC, replybuf);
+				if (status != MI_SUCCESS && conf->conf_dolog)
+				{
+					syslog(LOG_ERR, "%s: smfi_setreply() failed",
+					       dfc->mctx_jobid);
+				}
+
+				ret = SMFIS_REJECT;
+				result = DMARC_RESULT_REJECT;
+			}
+
+			if (conf->conf_copyfailsto != NULL)
+			{
+				status = dmarcf_addrcpt(ctx, conf->conf_copyfailsto);
+				if (status != MI_SUCCESS && conf->conf_dolog)
+				{
+					syslog(LOG_ERR, "%s: smfi_addrcpt() failed",
+					       dfc->mctx_jobid);
+				}
+			}
+		}
+
+		break;
+
+	  case DMARC_POLICY_QUARANTINE:		/* Explicit quarantine */
+		aresult = "fail";
+
+		if (conf->conf_overridemlm != NULL &&
+		    (dmarcf_checkhost(cc->cctx_host, conf->conf_overridemlm) ||
+		    (dmarcf_checkip((struct sockaddr *)&cc->cctx_ip, conf->conf_overridemlm))))
+		{
+			if (conf->conf_dolog)
+			{
+				syslog(LOG_INFO, "%s: overriding policy for mail from %s: MLM",
+				       dfc->mctx_jobid, dfc->mctx_fromdomain);
+			}
+			ret = SMFIS_ACCEPT;
+			result = DMARC_RESULT_OVRD_MAILING_LIST;
+		}
+		else
+		{
+			if (conf->conf_rejectfail && random() % 100 < pct &&
+			    conf->conf_holdquarantinedmessages)
+			{
+				snprintf(replybuf, sizeof replybuf,
+					 "quarantined by DMARC policy for %s",
+					 pdomain);
+
+				status = smfi_quarantine(ctx, replybuf);
+				if (status != MI_SUCCESS && conf->conf_dolog)
+				{
+					syslog(LOG_ERR, "%s: smfi_quarantine() failed",
+					       dfc->mctx_jobid);
+				}
+
+				ret = SMFIS_ACCEPT;
+				result = DMARC_RESULT_QUARANTINE;
+			}
+
+			if (conf->conf_copyfailsto != NULL)
+			{
+				status = dmarcf_addrcpt(ctx, conf->conf_copyfailsto);
+				if (status != MI_SUCCESS && conf->conf_dolog)
+				{
+					syslog(LOG_ERR, "%s: smfi_addrcpt() failed",
+					       dfc->mctx_jobid);
+				}
+			}
+		}
+
+		break;
+
+	  default:
+		aresult = "temperror";
+		ret = SMFIS_TEMPFAIL;
+		result = DMARC_RESULT_TEMPFAIL;
+		break;
+	}
+
+	/* prepare human readable dispositon string for later processing */
+	switch (result)
+	{
+	  case DMARC_RESULT_REJECT:
+		adisposition = "reject";
+		deliveryresult = "reject";
+		break;
+
+	  case DMARC_RESULT_QUARANTINE:
+		adisposition = "quarantine";
+		deliveryresult = "policy";
+		break;
+
+	  default:
+		adisposition = "none";
+		deliveryresult = "delivered";
+		break;
+	}
+
+	/*
 	**  Generate a failure report.
 	*/
 
@@ -2931,8 +3080,11 @@
 			                   "Auth-Failure: dmarc\n");
 
 			dmarcf_dstring_printf(dfc->mctx_afrf,
-			                      "Authentication-Results: %s; dmarc=fail header.from=%s\n",
-			                      authservid,
+			                      "Authentication-Results: %s;\n",
+			                      authservid);
+			dmarcf_dstring_printf(dfc->mctx_afrf,
+					      "     dmarc=%s (p=%s dis=%s) header.from=%s\n",
+			                      aresult, apolicy, adisposition,
 			                      dfc->mctx_fromdomain);
 
 			dmarcf_dstring_printf(dfc->mctx_afrf,
@@ -2949,6 +3101,20 @@
 			                      cc->cctx_host);
 
 			dmarcf_dstring_printf(dfc->mctx_afrf,
+			                      "Source-Port: %u\n",
+			                      cc->cctx_ip.ss_family == AF_INET6 ? ntohs(((struct sockaddr_in6*) &cc->cctx_ip)->sin6_port) : ntohs(((struct sockaddr_in*) &cc->cctx_ip)->sin_port));
+
+			dmarcf_dstring_printf(dfc->mctx_afrf,
+			                      "Identity-Alignment: %s%s%s\n",
+			                      align_dkim == DMARC_POLICY_DKIM_ALIGNMENT_PASS ? "dkim" : "",
+					      ((align_dkim == DMARC_POLICY_DKIM_ALIGNMENT_PASS) && (align_spf == DMARC_POLICY_SPF_ALIGNMENT_PASS)) ? ", " : ((align_dkim != DMARC_POLICY_DKIM_ALIGNMENT_PASS) && (align_spf != DMARC_POLICY_SPF_ALIGNMENT_PASS)) ? "none" : "",
+					      align_spf == DMARC_POLICY_SPF_ALIGNMENT_PASS ? "spf" : "");
+
+			dmarcf_dstring_printf(dfc->mctx_afrf,
+			                      "Delivery-Result: %s\n",
+			                      deliveryresult);
+
+			dmarcf_dstring_printf(dfc->mctx_afrf,
 			                      "Reported-Domain: %s\n\n",
 			                      dfc->mctx_fromdomain);
 
@@ -3015,151 +3181,6 @@
 		}
 	}
 
-	/*
-	**  Enact policy based on DMARC results.
-	*/
-
-	result = DMARC_RESULT_ACCEPT;
-
-	switch (policy)
-	{
-	  case DMARC_POLICY_ABSENT:		/* No DMARC record found */
-	  case DMARC_FROM_DOMAIN_ABSENT:	/* No From: domain */
-		aresult = "none";
-		ret = SMFIS_ACCEPT;
-		result = DMARC_RESULT_ACCEPT;
-		break;
-
-	  case DMARC_POLICY_NONE:		/* Alignment failed, but policy is none: */
-		aresult = "fail";		/* Accept and report */
-		ret = SMFIS_ACCEPT;
-		result = DMARC_RESULT_ACCEPT;
-		break;
-
-	  case DMARC_POLICY_PASS:		/* Explicit accept */
-		aresult = "pass";
-		ret = SMFIS_ACCEPT;
-		result = DMARC_RESULT_ACCEPT;
-		break;
-
-	  case DMARC_POLICY_REJECT:		/* Explicit reject */
-		aresult = "fail";
-
-		if (conf->conf_overridemlm != NULL &&
-		    (dmarcf_checkhost(cc->cctx_host, conf->conf_overridemlm) ||
-		    (dmarcf_checkip((struct sockaddr *)&cc->cctx_ip, conf->conf_overridemlm))))
-		{
-			if (conf->conf_dolog)
-			{
-				syslog(LOG_INFO, "%s: overriding policy for mail from %s: MLM",
-				       dfc->mctx_jobid, dfc->mctx_fromdomain);
-			}
-			ret = SMFIS_ACCEPT;
-			result = DMARC_RESULT_OVRD_MAILING_LIST;
-		}
-		else
-		{
-			if (conf->conf_rejectfail && random() % 100 < pct)
-			{
-				snprintf(replybuf, sizeof replybuf,
-					 "rejected by DMARC policy for %s", pdomain);
-
-				status = dmarcf_setreply(ctx, DMARC_REJECT_SMTP,
-							 DMARC_REJECT_ESC, replybuf);
-				if (status != MI_SUCCESS && conf->conf_dolog)
-				{
-					syslog(LOG_ERR, "%s: smfi_setreply() failed",
-					       dfc->mctx_jobid);
-				}
-
-				ret = SMFIS_REJECT;
-				result = DMARC_RESULT_REJECT;
-			}
-
-			if (conf->conf_copyfailsto != NULL)
-			{
-				status = dmarcf_addrcpt(ctx, conf->conf_copyfailsto);
-				if (status != MI_SUCCESS && conf->conf_dolog)
-				{
-					syslog(LOG_ERR, "%s: smfi_addrcpt() failed",
-					       dfc->mctx_jobid);
-				}
-			}
-		}
-
-		break;
-
-	  case DMARC_POLICY_QUARANTINE:		/* Explicit quarantine */
-		aresult = "fail";
-
-		if (conf->conf_overridemlm != NULL &&
-		    (dmarcf_checkhost(cc->cctx_host, conf->conf_overridemlm) ||
-		    (dmarcf_checkip((struct sockaddr *)&cc->cctx_ip, conf->conf_overridemlm))))
-		{
-			if (conf->conf_dolog)
-			{
-				syslog(LOG_INFO, "%s: overriding policy for mail from %s: MLM",
-				       dfc->mctx_jobid, dfc->mctx_fromdomain);
-			}
-			ret = SMFIS_ACCEPT;
-			result = DMARC_RESULT_OVRD_MAILING_LIST;
-		}
-		else
-		{
-			if (conf->conf_rejectfail && random() % 100 < pct &&
-			    conf->conf_holdquarantinedmessages)
-			{
-				snprintf(replybuf, sizeof replybuf,
-					 "quarantined by DMARC policy for %s",
-					 pdomain);
-
-				status = smfi_quarantine(ctx, replybuf);
-				if (status != MI_SUCCESS && conf->conf_dolog)
-				{
-					syslog(LOG_ERR, "%s: smfi_quarantine() failed",
-					       dfc->mctx_jobid);
-				}
-
-				ret = SMFIS_ACCEPT;
-				result = DMARC_RESULT_QUARANTINE;
-			}
-
-			if (conf->conf_copyfailsto != NULL)
-			{
-				status = dmarcf_addrcpt(ctx, conf->conf_copyfailsto);
-				if (status != MI_SUCCESS && conf->conf_dolog)
-				{
-					syslog(LOG_ERR, "%s: smfi_addrcpt() failed",
-					       dfc->mctx_jobid);
-				}
-			}
-		}
-
-		break;
-
-	  default:
-		aresult = "temperror";
-		ret = SMFIS_TEMPFAIL;
-		result = DMARC_RESULT_TEMPFAIL;
-		break;
-	}
-
-	/* prepare human readable dispositon string for later processing */
-	switch (result)
-	{
-	  case DMARC_RESULT_REJECT:
-		adisposition = "reject";
-		break;
-
-	  case DMARC_RESULT_QUARANTINE:
-		adisposition = "quarantine";
-		break;
-
-	  default:
-		adisposition = "none";
-		break;
-	}
-
 	if (conf->conf_dolog)
 	{
 		syslog(LOG_INFO, "%s: %s %s", dfc->mctx_jobid,