opendkim-ng 3.0.0-beta11 (project renamed to PhoenixDKIM on 21 May 2026)
21 May 2026
A large release. The headline is a systematic compiler warning cleanup that turned up a number of real bugs along the way. There are also new features, several security fixes, and a handful of upstream bug fixes.
New features
-
Authentication-Results now includes header.a (signing algorithm) and header.s (selector).
-
New SyslogName configuration option to set the syslog identity string.
-
odkim.internal_ip() is now available in the screen and final Lua policy hooks.
-
The OpenSSL version string is included in build-config.h and reported by the -V flag.
-
OpenSSL 4 build support.
Removals
-
Removed QUERY_CACHE: libopendkim's BerkeleyDB-backed DNS result cache.
-
Removed POPAUTH (POP-before-SMTP) support.
Security fixes
-
Sandboxed Lua policy hooks against dangerous standard libraries (io, os, package, etc.).
-
Fixed a TXT chunk-length out-of-bounds read in DNS key extraction.
-
Fixed an Authentication-Results stripping bypass via a trailing-dot authserv-id.
-
Fixed a race in mlfi_connect: the current configuration was read without holding a reference count.
-
Fixed a related race in dkimf_add_signrequest, which was reading per-connection configuration from the global curconf.
-
Fixed a too-small buffer for the report address (user@host worst case).
-
Fixed undefined behaviour: (int) buflen cast is UB when buflen > INT_MAX.
Bug fixes
-
Fixed dkim_ohdrs z= decode: it was writing into plist storage, using the wrong strlcpy size, and ignoring the scratch buffer.
-
Fixed dkimf_xs_delheader ignoring its idx argument.
-
Fixed potential dereference of an uninitialised sig pointer in dkim_eoh_verify.
-
Fixed potential use of an uninitialised ar in the mlfi_eom header-only path.
-
Fixed dkim_diffheaders stub falling off the end of a non-void function.
-
Fixed DKIM_SIGFLAG_PROCESSED not being set in all dkim_sig_process error paths.
-
Fixed missing dn_expand return-value check in the DNS qdcount loop.
-
Fixed an off-by-one in snprintf truncation detection in key queries.
-
Fixed missing truncation detection in Authentication-Results field copies in the ares parser.
-
Zero per-sign-request private key data before freeing.
-
Fixed missing leading space on Authentication-Results header when SMFIP_HDR_LEADSPC is not negotiated.
-
Quote header.b values in Authentication-Results (bug #235).
-
Constrain the header.b substring correctly for duplicate signatures (bug #233).
-
Handle header fields wrapped before any content (bug #226).
-
Remove the upper bound on the canonicalisation buffer size.
-
Fix quote handling in dkim_mail_parse_multi().
-
Make the standard (non-unbound) resolver DNSSEC-aware.
-
Protect ub_ctx_config() calls with a mutex (issue #14).
-
Widen the password-file critical section in dkimf_securefile (issue #8).
-
RequiredHeaders now reports the specific missing header and rejects the message (issue #28).
-
Do not skip the body when only one canonicalisation mode has finished (issue #15).
-
Reject non-printable characters in the domain and selector passed to dkim_sign() (feature #190).
Compiler warning cleanup
As a first step, CMake hardening infrastructure was added to the build, enabling a set of warnings that had previously been absent or silently suppressed: -Wcast-qual, -Wmissing-prototypes, -Wshadow, -Wsign-compare, -Wpointer-sign, -Wformat-truncation, -Wunused-parameter, -Wreturn-type. The result was a substantial number of warnings across the daemon, library, miltertest, and test suite. These were then addressed systematically. Several real bugs were found and fixed in the process (listed above).
-
-Wcast-qual: extensive const-qualification work throughout libopendkim, opendkim, and miltertest. The dkim_options() API was split into separate dkim_setopt() and dkim_getopt() functions to make the const split clean. Unavoidable legacy libmilter cast sites are annotated.
-
-Wmissing-prototypes: file-internal helpers marked static; missing prototypes hoisted into headers.
-
-Wshadow: shadowing locals renamed or removed across the daemon, library, and tests.
-
-Wsign-compare: signed/unsigned comparison fixes; loop counters and sentinel values correctly typed; a wraparound in dkim_get_sigsubstring fixed.
-
-Wpointer-sign: u_char/char pointer mismatches resolved at libopendkim API boundaries.
-
-Wunused-parameter, -Wunused-variable, -Wreturn-type: remaining stragglers cleaned up.