Skip to content

check.milter: fail_open does not cover a milter session-dial failure #866

Description

@marcominetti

Summary

check.milter's fail_open directive is documented to let a message through when the milter can't be consulted, but it silently doesn't cover one specific failure mode: the milter being completely unreachable when maddy tries to establish a session.

Root cause

CheckStateForMsg (internal/check/milter/milter.go) dials the milter backend via c.cl.Session() and returns any error unconditionally. This happens before a *state exists, so the failure never reaches ioError() — the only place fail_open is actually checked. Result: with fail_open set, a message is still hard-rejected (a real SMTP-level error handed back to the original sender) if the milter is simply down — exactly the case fail_open exists to guard against.

Reproduction

Configure check.milter with fail_open: true pointing at a milter address that's genuinely unreachable (e.g. nothing listening on that port), then send a message through. Expected: message accepted unchecked, per fail_open. Actual: a hard SMTP-level rejection.

Fix

I've prepared and tested a fix — handles the dial failure the same way ioError() already handles a later I/O failure — and opened it as #865, with a regression test that fails against unpatched code and passes with the fix.

Apologies for the PR arriving before this issue — I realize CONTRIBUTING.md's process is to raise the issue first. Filing this now so there's a proper place to discuss the bug alongside the PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions