add "Fail" transport, that immediately fails delivery

allows configs that prevent outgoing deliveries (globally, per domain,
or per account) from/to certain domains.

for issue #347
This commit is contained in:
Mechiel Lukkien
2025-05-15 17:59:49 +02:00
parent 91bfff220e
commit bb438488c5
7 changed files with 123 additions and 4 deletions

View File

@ -1058,6 +1058,33 @@ func PrepareStaticConfig(ctx context.Context, log mlog.Log, configFile string, c
}
}
checkTransportFail := func(name string, t *config.TransportFail) {
addTransportErrorf := func(format string, args ...any) {
addErrorf("transport %s: %s", name, fmt.Sprintf(format, args...))
}
if t.SMTPCode == 0 {
t.Code = smtp.C554TransactionFailed
} else if t.SMTPCode/100 != 4 && t.SMTPCode/100 != 5 {
addTransportErrorf("smtp code %d must be 4xx or 5xx", t.SMTPCode/100)
} else {
t.Code = t.SMTPCode
}
if len(t.SMTPMessage) > 256 {
addTransportErrorf("message must be <= 256 characters")
}
for _, c := range t.SMTPMessage {
if c < ' ' || c >= 0x7f {
addTransportErrorf("message cannot contain control characters including newlines, and must be ascii-only")
}
}
t.Message = t.SMTPMessage
if t.Message == "" {
t.Message = "transport fail: explicit immediate delivery failure per configuration"
}
}
for name, t := range c.Transports {
addTransportErrorf := func(format string, args ...any) {
addErrorf("transport %s: %s", name, fmt.Sprintf(format, args...))
@ -1084,6 +1111,10 @@ func PrepareStaticConfig(ctx context.Context, log mlog.Log, configFile string, c
n++
checkTransportDirect(name, t.Direct)
}
if t.Fail != nil {
n++
checkTransportFail(name, t.Fail)
}
if n > 1 {
addTransportErrorf("cannot have multiple methods in a transport")
}