findings of the security review of stage 1

The review of d254a99..fd29468 (read-only, a separate agent) found all
five fixes sound and nothing above low. Fixed here:

- The M1 e2e step passed on the unfixed code: the stranger's RSET between
  MAIL FROMs ends the transaction, Postfix's mail_reset() calls
  milter_abort(), and the old code released the slot too. The stranger now
  keeps one MAIL FROM open (strangerHoldsMailFrom) while the domain's own
  application sends; under the old code that slot was the domain's one.
- A domain import could still store a report address on the server's own
  name (W1's form rule only): checkDomainImport refuses one that is not
  the domain's own hosted address. Not a mailbox either way, but the
  panel would show an address the server refuses. Cases in
  TestDomainImportIsCheckedLikeTheForms.
- DeleteDomain matches the reports' domain without regard to case.
- A cut that fails after the journal rows were written says the rows were
  written.
- dmarc.Service.Resync and inbound.Service.Resync are serialised like
  app.Service.Resync (W3's shape, outside its diff).

Left as the review's nit: three ApplicationByLogin lookups for a refused
MAIL FROM (a refusal is rare; the store is local).

go test ./internal/dmarc ./internal/inbound ./internal/store; the import
test; GOOS=linux go vet ./test/e2e.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-17 22:13:36 +03:00
co-authored by Claude Opus 5.5
parent 3a8e19b71c
commit 4433688500
7 changed files with 61 additions and 26 deletions
+7
View File
@@ -5,6 +5,7 @@ package dmarc
import (
"sort"
"strings"
"sync"
"github.com/mixeme/selfpost/internal/dnscheck"
"github.com/mixeme/selfpost/internal/postfix"
@@ -22,6 +23,10 @@ type Service struct {
maps Maps
hostname string
enabled bool
// resyncMu makes a rebuild's read and write one step, as app.Service's
// (security audit 2026-10-17, W3; the review of stage 1).
resyncMu sync.Mutex
}
// NewService builds the DMARC ingest service.
@@ -34,6 +39,8 @@ func (s *Service) Enabled() bool { return s.enabled }
// Resync rebuilds the Postfix allow-list and transport maps from SQLite.
func (s *Service) Resync() error {
s.resyncMu.Lock()
defer s.resyncMu.Unlock()
if !s.enabled {
return s.maps.RebuildDMARCMaps(postfix.DMARCMapsConfig{})
}