From 186538fb578e09cbe7af820ab3989a92105553cd Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Wed, 1 Nov 2023 20:38:43 +0100 Subject: [PATCH] when composing a dsn, try harder to dkim-sign it, also with higher-level domain than full mail hostname e.g. typical setup is a hostname mail.. and dsns can be sent from postmaster@mail.. so it helps to look for dkim keys for , and use them when signing. instead of looking for dkim keys for mail., which won't typically exist. similar to recent commit that added outgoing dmarc aggregate reports. --- dsn/dsn.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/dsn/dsn.go b/dsn/dsn.go index 741434b906..a9147ae342 100644 --- a/dsn/dsn.go +++ b/dsn/dsn.go @@ -17,6 +17,7 @@ import ( "time" "github.com/mjl-/mox/dkim" + "github.com/mjl-/mox/dns" "github.com/mjl-/mox/message" "github.com/mjl-/mox/mlog" "github.com/mjl-/mox/mox-" @@ -365,14 +366,28 @@ func (m *Message) Compose(log *mlog.Log, smtputf8 bool) ([]byte, error) { data := msgw.w.Bytes() + // Add DKIM signature for domain, even if higher up than the full mail hostname. + // This helps with an assumed (because default) relaxed DKIM policy. If the DMARC + // policy happens to be strict, the signature won't help, but won't hurt either. fd := m.From.IPDomain.Domain - confDom, _ := mox.Conf.Domain(fd) - if len(confDom.DKIM.Sign) > 0 { - if dkimHeaders, err := dkim.Sign(context.Background(), m.From.Localpart, fd, confDom.DKIM, smtputf8, bytes.NewReader(data)); err != nil { + var zerodom dns.Domain + for fd != zerodom { + confDom, ok := mox.Conf.Domain(fd) + if !ok { + var nfd dns.Domain + _, nfd.ASCII, _ = strings.Cut(fd.ASCII, ".") + _, nfd.Unicode, _ = strings.Cut(fd.Unicode, ".") + fd = nfd + continue + } + + dkimHeaders, err := dkim.Sign(context.Background(), m.From.Localpart, fd, confDom.DKIM, smtputf8, bytes.NewReader(data)) + if err != nil { log.Errorx("dsn: dkim sign for domain, returning unsigned dsn", err, mlog.Field("domain", fd)) } else { data = append([]byte(dkimHeaders), data...) } + break } return data, nil