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
+4 -3
View File
@@ -133,9 +133,10 @@ than the default «meaningful step» rule in [§ Commits and release build](#com
| 20 | audit-2026-10-12 stage 0: release hygiene | `2.4.2` (PATCH) |
| 21 | audit-2026-10-12 stages 1 and 2 | `2.5.0` |
| 22 | audit-2026-10-12 stage 2b: the log tailer | `2.5.1` |
| 23 | audit-2026-10-12 stage 3 | `2.5.2` |
| 24 | audit-2026-10-12 stage 4 | `2.5.3` |
| 25 | audit-2026-10-12 stage 5 | `2.6.0` |
| 23 | audit-2026-10-12 stage 2c: the sender check reads From: as OpenDKIM does | `2.5.2` |
| 24 | audit-2026-10-12 stage 3 | `2.5.3` |
| 25 | audit-2026-10-12 stage 4 | `2.5.4` |
| 26 | audit-2026-10-12 stage 5 | `2.6.0` |
Docs-only prep (checklists in plans, no product code) uses the same per-step
commit rule but **no** version cut until the next product stage ships.
+1 -1
View File
@@ -42,7 +42,7 @@ in `git log` and [CHANGELOG.md](../CHANGELOG.md).
| from-header-binding | Hold a message's `From:` header against the application that sends it | shipped `2.4.0` | 9/9 | [plans/from-header-binding.md](plans/from-header-binding.md) |
| panel-redesign | Panel redesign (accepted mockups, design contract) | shipped `2.0.0` | 27/27 | [plans/panel-redesign.md](plans/panel-redesign.md) |
| schema-squash | Squash SQLite migrations into a 2.x baseline | built in panel-redesign (stage 1) | — | [plans/panel-redesign.md](plans/panel-redesign.md) |
| audit-2026-10-12 | Follow-ups of the 2026-10-12 full-tree code audit, seven stages | in progress (stage 0 shipped `2.4.2`, stages 1+2 `2.5.0`; next stage 2b → `2.5.1`) | 30/62 | [audit-2026-10-12.md](audit-2026-10-12.md) |
| audit-2026-10-12 | Follow-ups of the 2026-10-12 full-tree code audit, seven stages | in progress (stage 0 shipped `2.4.2`, stages 1+2 `2.5.0`; next stage 2b → `2.5.1`) | 30/65 | [audit-2026-10-12.md](audit-2026-10-12.md) |
**Recommended order** (not binding; owner, 2026-10-09: feature order follows
development convenience): **panel-redesign** shipped as `2.0.0` (2026-10-11) and