diff --git a/CHANGES-202605.md b/CHANGES-202605.md index d6f075e2..d0a869ca 100644 --- a/CHANGES-202605.md +++ b/CHANGES-202605.md @@ -90,6 +90,9 @@ Significant gaps between the generated aggregate report XML and RFC 7489 require - **Distinct `ReportCommand` exit code for fully-suppressed reports**: When every recipient of a forensic report is suppressed by `NoReportsList`, StaleMARC, or the suppressions table, `opendmarc-reports --forensic` now exits `2` instead of `0`, and the milter logs this at `LOG_INFO` rather than treating it as a `ReportCommand` failure (previously indistinguishable from a normal send in the logs). (#424) - **`--archive-dir`**: New option saves a copy of every outbound report -- the full message as handed to SMTP, not just the gzipped XML or AFRF attachment -- to a directory for later review (e.g. RFC-compliance checking). Applies to both aggregate and forensic modes; suppressed and `--test`-mode reports are not archived. (#424) - **Bare `NoReportsList` domain entries now also suppress `--forensic` reports**: Previously a bare sending-domain entry only suppressed aggregate reports (via `--skipdomains`); the manpage explicitly noted "no effect on failure report (ruf=) suppression in the milter itself." `opendmarc-reports --forensic` now reads the `Reported-Domain` field from the AFRF message and checks it against the same `--skipdomains`/`NoReportsList`, StaleMARC, and suppressions-DB logic the aggregate path uses, discarding the report (exit code 2) if the domain is suppressed. Still has no effect when `ReportCommand` pipes directly to `sendmail` rather than through `opendmarc-reports`, since only the latter performs the check. (#425) +- **Milter-generated failure reports now use `X-Mailer` instead of `User-Agent` for version identification**: `opendmarc-reports` already labelled aggregate reports with `X-Mailer: opendmarc-reports v`, the long-established email convention for identifying the software that generated a message. The milter's own AFRF failure-report path used `User-Agent: %s/%s` instead, so the two report types disagreed on which header to use. Both now use `X-Mailer`. +- **`opendmarc-reports`' version string now includes the git hash on development builds**: The milter's `DMARCF_VERSION` already ran `git describe --tags --dirty` at configure time so dev builds show a hash suffix (e.g. `1.4.2-3-gabc1234-dirty`); `opendmarc-reports` used the plain release version with no such logic, so identical dev builds reported different version strings depending on which program authored the report. `configure.ac` now `AC_SUBST`s `DMARCF_VERSION`, and `opendmarc-reports.in` uses it in place of `@VERSION@`. +- **`opendmarc-reports --forensic` now leaves a `Received:` trace when relaying**: A report relayed by the milter's `ReportCommand` directly to `sendmail -t` picks up a normal `Received:` header from the local MTA, but `--forensic` mode talks to the configured SMTP server directly via `Net::SMTP` and otherwise passes the milter-composed message through completely untouched, leaving no indication the message passed through `opendmarc-reports` at all. A single `Received: by (opendmarc-reports v) via forensic relay; ` line is now prepended before sending (and before the message is archived via `--archive-dir`, so the archived copy matches what was actually sent), applied identically regardless of `--verp`. --- diff --git a/configure.ac b/configure.ac index 735fb882..577b4e03 100644 --- a/configure.ac +++ b/configure.ac @@ -82,6 +82,7 @@ fi AC_MSG_RESULT([$DMARCF_VERSION]) AC_DEFINE_UNQUOTED([DMARCF_VERSION], ["$DMARCF_VERSION"], [Version string, including git hash on development builds]) +AC_SUBST([DMARCF_VERSION]) # # Hexadecimal version, for use in generating dmarc.h diff --git a/opendmarc/opendmarc.c b/opendmarc/opendmarc.c index b1d7c0fd..618105c9 100644 --- a/opendmarc/opendmarc.c +++ b/opendmarc/opendmarc.c @@ -3635,7 +3635,7 @@ mlfi_eom(SMFICTX *ctx) "Version: 1\n"); dmarcf_dstring_printf(dfc->mctx_afrf, - "User-Agent: %s/%s\n", + "X-Mailer: %s/%s\n", DMARCF_PRODUCTNS, DMARCF_VERSION); dmarcf_dstring_cat(dfc->mctx_afrf, diff --git a/reports/opendmarc-reports.in b/reports/opendmarc-reports.in index c79975e9..a6f08689 100755 --- a/reports/opendmarc-reports.in +++ b/reports/opendmarc-reports.in @@ -30,7 +30,7 @@ require LWP::UserAgent; # general my $progname = basename($0); -my $version = "@VERSION@"; +my $version = "@DMARCF_VERSION@"; my $verbose = 0; my $helponly = 0; my $showversion = 0; @@ -753,6 +753,13 @@ if ($forensic) $smtp = smtp_connect(); exit(1) unless defined($smtp); + # Mark the relay hop so a recipient (or an admin troubleshooting + # delivery) can tell this report passed through opendmarc-reports + # rather than going straight out via the milter's ReportCommand + # (e.g. "sendmail -t"), which leaves no such trace of its own. + my $received_datestr = strftime("%a, %e %b %Y %H:%M:%S %z (%Z)", localtime); + $message = "Received: by " . hostfqdn() . " (opendmarc-reports v$version) via forensic relay; $received_datestr\n" . $message; + my $archive_label = $rcpts[0]; $archive_label .= "+" . (scalar(@rcpts) - 1) if @rcpts > 1; archive_report($archive_label, $message);