diff --git a/libopendmarc/dmarc.h b/libopendmarc/dmarc.h index d7b3317..19a8772 100644 --- a/libopendmarc/dmarc.h +++ b/libopendmarc/dmarc.h @@ -75,6 +75,9 @@ extern "C" { #define DMARC_POLICY_QUARANTINE (17) /* Policy says to quarantine message */ #define DMARC_POLICY_NONE (18) /* Policy says to monitor and report */ +#define DMARC_USED_POLICY_IS_P (19) /* Domain policy taken (aka 'p')*/ +#define DMARC_USED_POLICY_IS_SP (20) /* Sub-domain policy taken (aka 'sp')*/ + #ifndef OPENDMARC_POLICY_C typedef struct dmarc_policy_t DMARC_POLICY_T; #endif @@ -140,6 +143,7 @@ u_char ** opendmarc_policy_fetch_rua(DMARC_POLICY_T *pctx, u_char *list_buf, u_char ** opendmarc_policy_fetch_ruf(DMARC_POLICY_T *pctx, u_char *list_buf, size_t size_of_buf, int constant); OPENDMARC_STATUS_T opendmarc_policy_fetch_utilized_domain(DMARC_POLICY_T *pctx, u_char *buf, size_t buflen); OPENDMARC_STATUS_T opendmarc_policy_query_dmarc_xdomain(DMARC_POLICY_T *pctx, u_char *uri); +OPENDMARC_STATUS_T opendmarc_get_policy_source_taken(DMARC_POLICY_T *pctx); /* * TLD processing diff --git a/libopendmarc/opendmarc_policy.c b/libopendmarc/opendmarc_policy.c index cee7aa2..5b5caac 100644 --- a/libopendmarc/opendmarc_policy.c +++ b/libopendmarc/opendmarc_policy.c @@ -1466,6 +1466,28 @@ opendmarc_policy_fetch_utilized_domain(DMARC_POLICY_T *pctx, u_char *buf, size_t return DMARC_PARSE_OKAY; } +/************************************************************************** +** OPENDMARC_GET_POLICY_SOURCE_TAKEN -- Which policy was actually used +** +** Parameters: +** pctx -- A Policy context +** Returns: +** DMARC_PARSE_ERROR_NULL_CTX -- pctx == NULL +** DMARC_USED_POLICY_IS_P -- Domain policy is used +** DMARC_USED_POLICY_IS_SP -- Sub-domain policy is used +***************************************************************************/ +OPENDMARC_STATUS_T +opendmarc_get_policy_source_taken(DMARC_POLICY_T *pctx) +{ + + if (pctx == NULL) + return DMARC_PARSE_ERROR_NULL_CTX; + if (pctx->organizational_domain != NULL && pctx->sp != DMARC_RECORD_P_UNSPECIFIED) + return DMARC_USED_POLICY_IS_SP; + else + return DMARC_USED_POLICY_IS_P; +} + /****************************************************************************** ** OPENDMARC_POLICY_LIBRARY_DNS_HOOK -- Internal hook for dmarc_dns_get_record *******************************************************************************/ diff --git a/opendmarc/opendmarc.c b/opendmarc/opendmarc.c index bfd9a48..7186b47 100644 --- a/opendmarc/opendmarc.c +++ b/opendmarc/opendmarc.c @@ -2018,7 +2018,9 @@ mlfi_eom(SMFICTX *ctx) int result; sfsistat ret = SMFIS_CONTINUE; OPENDMARC_STATUS_T ostatus; + char *apolicy = NULL; char *aresult = NULL; + char *adisposition = NULL; char *hostname = NULL; char *authservid = NULL; char *spfaddr; @@ -2673,6 +2675,24 @@ mlfi_eom(SMFICTX *ctx) align_dkim); dmarcf_dstring_printf(dfc->mctx_histbuf, "align_spf %d\n", align_spf); + // prepare human readable policy string for later processing + switch (opendmarc_get_policy_source_taken(cc->cctx_dmarc) == DMARC_USED_POLICY_IS_SP ? sp : p) + { + case DMARC_RECORD_P_QUARANTINE: + apolicy = "QUARANTINE"; + break; + + case DMARC_RECORD_P_REJECT: + apolicy = "REJECT"; + break; + + case DMARC_RECORD_P_UNSPECIFIED: + case DMARC_RECORD_P_NONE: + default: + apolicy = "NONE"; + break; + } + /* ** Generate a failure report. */ @@ -3007,6 +3027,22 @@ mlfi_eom(SMFICTX *ctx) 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, @@ -3017,11 +3053,11 @@ mlfi_eom(SMFICTX *ctx) if (ret != SMFIS_TEMPFAIL && ret != SMFIS_REJECT) { snprintf(header, sizeof header, - "%s%s%s; dmarc=%s header.from=%s", + "%s%s%s; dmarc=%s (p=%s dis=%s) header.from=%s", authservid, conf->conf_authservidwithjobid ? "/" : "", conf->conf_authservidwithjobid ? dfc->mctx_jobid : "", - aresult, dfc->mctx_fromdomain); + aresult, apolicy, adisposition, dfc->mctx_fromdomain); if (dmarcf_insheader(ctx, 1, AUTHRESULTSHDR, header) == MI_FAILURE)