audit: stage 2c - the sender check reads From: as OpenDKIM does (owner's decision)
test / test (push) Canceled after 0s

Owner, 2026-10-14, after reading OpenDKIM's source together
(dkim_mail_parse, called in mlfi_eoh on the first From:; SenderHeaders is
unset in build/opendkim.conf): "Да" to porting the parser so that the check
decides by the address OpenDKIM will take. The scan of the display name and
comments for another sender of the server - a guard against two parsers
parting ways, and the reason L8 is half closed - then goes.

New stage 2c (three lines) after 2.5.1 and before stage 3: the port from
the version the image runs, checked against OpenDKIM on the stand with
generated lines, then docs and wording. Stages 3 and 4 move to 2.5.3 and
2.5.4 (development.md's planned cuts). Plan 65 lines, roadmap 30/65.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-14 18:19:34 +03:00
co-authored by Claude Opus 5.5
parent 57142b21b5
commit 5dcff8c2b9
3 changed files with 44 additions and 6 deletions
+39 -2
View File
@@ -840,7 +840,44 @@ order - each stands on the one before.
refusal's line and a recovered row), guide § Outbound log and § Health,
schema-migrations.md for the mark on `sender_check_days`. — **Sonnet**
### Stage 3 — persistence and restore (M1–M5, L1–L4, L7) → `2.5.2`
### Stage 2c — the sender check reads From: as OpenDKIM does → `2.5.2`
Decided by the owner on 2026-10-14, after reading OpenDKIM's source together
(libopendkim `dkim_mail_parse`, called in `mlfi_eoh` on the first `From:`
with `SenderHeaders` unset - `build/opendkim.conf` sets none): the signing
address is the one in angle brackets, or a bare address, found while quoted
strings and comments are skipped; encoded words are not decoded. The check's
scan of the display name and comments for another sender of the server is a
guard against two parsers parting ways - and it is what makes L8 half
closed. This stage replaces the guard with the parser itself. Stage 3 and
those after it move up one patch number each.
- [ ] **Port `dkim_mail_parse` to Go, from the version the image runs**
(Debian bookworm's opendkim 2.11.0~beta2 source package, not upstream's
develop branch), line for line, with its tokenizer
(`dkim_mail_first_special`, `dkim_mail_token`). The check then decides by
the address OpenDKIM will take: the application's - any address of its
domain, or one of its list - passes, whatever the display name or a
comment holds; anything else, a parse failure included, is refused. One
`From:` line and one address stay required. The scan for another sender
of the server in the name, in a comment and in a decoded name goes, and
with it the reason that told an application which domains are hosted
here (L8 closed; security.md's accepted risk struck). Whether the "one @
outside quotes" rule is still needed is decided against the port, and
said. - **Opus**
- [ ] **The port checked against OpenDKIM itself.** On the stand, several
hundred generated `From:` lines - quotes, escapes, comments nested and
open, groups, brackets, encoded words, a second domain of the server in
every place - are sent; for each, the domain the port names must be the
`d=` the message arrives signed with, or both say "no signature". The
shared files of lines (`from-lines-passed.txt`, `from-lines-other.txt`)
are kept: the second one's test becomes "never signed for {other}"
rather than "refused". - **Opus**
- [ ] Docs and wording: help topic sender-check and guide § Who an
application may send as (mockup first), security.md § Mail path,
CHANGELOG. - **Sonnet**
### Stage 3 — persistence and restore (M1–M5, L1–L4, L7) → `2.5.3`
- [ ] **Consume the manifest after the resync succeeds** (`CheckRestore` reports;
`run` deletes after `resyncAfterRestore` returns nil). Test: Resync fails →
@@ -865,7 +902,7 @@ order - each stands on the one before.
package. — **Opus**
- [ ] Docs: security.md § Backup; guide § Backup. — **Sonnet**
### Stage 4 — panel behaviour (M8, M11, L10–L19) → `2.5.3`
### Stage 4 — panel behaviour (M8, M11, L10–L19) → `2.5.4`
- [ ] Login: dummy bcrypt on unknown user; a test that measures both paths within
a tolerance. Account password change gets its own limiter bucket. Login