review follow-up: close the gaps left by the phase1-6 pass
test / test (push) Has been cancelled

Verified the tree against docs/plans/code-review-2026-08.md and finished the
tasks that were only partly done, plus two defects the pass introduced.

- bcrypt: the setup account was still hashed at DefaultCost (10). The work
  factor now has one definition, auth.BcryptCost = 12, used everywhere.
- rate limiter: protecting blocked buckets from eviction was unbounded — an
  attacker with many source addresses could grow the map by making each one
  fail its way to blocked. Blocked buckets are now evicted past
  maxBuckets * 4, nearest expiry first, logged once per window. Tests cover
  both halves.
- postqueue: the 5s timeout left the output size unbounded; reads are now
  capped at 4 MiB and report truncation.
- spec references: the ~76 `spec N` citations CHANGELOG [0.5.0] claimed were
  gone are removed from build/, deploy/, the first two migrations and the
  release workflow, with the affected comment paragraphs re-wrapped. Comments
  only; shell/YAML/SQL syntax re-checked.
- schema-migrations.md: schema section was headed v9 with the chain at v10,
  and three links pointed at deleted plan files.
- internal/configsafe: the shared empty/forbidden-character check behind the
  OpenDKIM and Postfix config writers; each writer keeps its own forbidden set.
- dropped the parseDomainRateLimitForm/parseAppRateLimitForm pass-throughs
  left behind by the parser merge (only their own tests still called them).
- plan doc now carries a status table: what shipped, what was already in
  place, what was declined (//go:build linux for the /proc reader) and the
  open CSRF-token question.

Not done, each its own phase: typed template data structs, log/slog, DMARC
service and handler tests, error-page/corrupted-backup tests, backup re-auth.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-08-19 20:03:05 +03:00
co-authored by Claude Opus 5
parent 4204ee279c
commit ab2cd885c4
34 changed files with 586 additions and 318 deletions
+35 -10
View File
@@ -15,16 +15,8 @@ rate limit is correct for a non-default level-1 window. Schema migration
- Code review plan (`docs/plans/code-review-2026-08.md`) — full codebase audit
covering architecture, code quality, security, GUI, tests, documentation, and
AGPL compliance. 38 findings across 11 categories with a prioritised
implementation plan in 6 phases.
### Removed
- Plan documents for already-shipped features: `domain-stats-auto-ratelimit`,
`dmarc-reports`, `inbound-relay`, `panel-docs`, `queue-retries`,
`send-log-retention`. Only unimplemented plans remain in `docs/plans/`.
### Added
implementation plan in 6 phases, and a status table recording what was
implemented, what was already in place, and what was declined.
- Roadmap item and plan for `/preflight` installation check page
([docs/plans/preflight.md](docs/plans/preflight.md)) — instance-level
infrastructure verification (rDNS, TLS, ports, HELO banner, proxy headers,
@@ -46,6 +38,21 @@ rate limit is correct for a non-default level-1 window. Schema migration
### Fixed
- The setup account's password is hashed at bcrypt cost `12` like every other
panel password; it was still being written at `bcrypt.DefaultCost` (10). The
work factor now has one definition, `auth.BcryptCost`. bcrypt records the
cost in the hash, so existing passwords keep verifying unchanged.
- Login/setup rate limiter: protecting blocked buckets from eviction is now
bounded. Blocked buckets are still never evicted to make room, but past
`maxBuckets × 4` they are evicted too (nearest expiry first) — otherwise an
attacker with many source addresses could grow the bucket map without limit
by making each address fail its way to blocked. The overflow is logged at
most once per window.
- `postqueue -p` output is bounded to 4 MiB (the timeout alone left the size of
the listing, and therefore the panel's allocation, up to the queue).
- [schema-migrations.md](docs/schema-migrations.md): the schema section was
still headed `v9` while the chain head is `v10`, and three links pointed at
plan files deleted when those features shipped.
- postqueue reader is now time-bounded: `postqueue -p` runs under a 5-second
context timeout so a stuck queue command cannot hang the queue panel path
indefinitely.
@@ -96,6 +103,18 @@ rate limit is correct for a non-default level-1 window. Schema migration
### Changed
- Extracted `internal/configsafe` — the empty-value and forbidden-character
check every generated config file shares. Each writer keeps its own forbidden
set next to the file it protects (an OpenDKIM table and a Postfix map break on
different characters); only the check itself is shared.
- Build, deploy and migration comments no longer cite the archived
specification. The `spec N` references CHANGELOG `[0.5.0]` said were gone
survived in `build/`, `deploy/`, the first two migrations and the release
workflow; they are removed and the affected comment paragraphs re-wrapped.
Comments only — no build or configuration behaviour changes.
- Dropped the `parseDomainRateLimitForm` / `parseAppRateLimitForm` pass-through
wrappers left behind when the two parsers were merged: nothing but their own
tests still called them.
- Extracted shared helpers: `internal/atomicfile` (atomic temp-write+rename) and
`internal/supervisor` (supervisorctl start/signal wrappers), and reused them in
domain/postfix code paths.
@@ -130,6 +149,12 @@ rate limit is correct for a non-default level-1 window. Schema migration
version-cut table through `1.9.1`; [schema-migrations.md](docs/schema-migrations.md)
last-updated note. No behaviour change.
### Removed
- Plan documents for already-shipped features: `domain-stats-auto-ratelimit`,
`dmarc-reports`, `inbound-relay`, `panel-docs`, `queue-retries`,
`send-log-retention`. Only unimplemented plans remain in `docs/plans/`.
## [1.9.1] - 2026-08-19
Port-25 Postfix startup when inbound relay, DMARC ingest, or the inbound antispam