# 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.

Back to announcements