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.<domain>. and dsns can be sent from
postmaster@mail.<domain>. so it helps to look for dkim keys for <domain>, and
use them when signing. instead of looking for dkim keys for mail.<domain>,
which won't typically exist.  similar to recent commit that added outgoing
dmarc aggregate reports.
This commit is contained in:
Mechiel Lukkien 2023-11-01 20:38:43 +01:00
parent f7686b7db8
commit 186538fb57
No known key found for this signature in database

View file

@ -17,6 +17,7 @@ import (
"time" "time"
"github.com/mjl-/mox/dkim" "github.com/mjl-/mox/dkim"
"github.com/mjl-/mox/dns"
"github.com/mjl-/mox/message" "github.com/mjl-/mox/message"
"github.com/mjl-/mox/mlog" "github.com/mjl-/mox/mlog"
"github.com/mjl-/mox/mox-" "github.com/mjl-/mox/mox-"
@ -365,14 +366,28 @@ func (m *Message) Compose(log *mlog.Log, smtputf8 bool) ([]byte, error) {
data := msgw.w.Bytes() 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 fd := m.From.IPDomain.Domain
confDom, _ := mox.Conf.Domain(fd) var zerodom dns.Domain
if len(confDom.DKIM.Sign) > 0 { for fd != zerodom {
if dkimHeaders, err := dkim.Sign(context.Background(), m.From.Localpart, fd, confDom.DKIM, smtputf8, bytes.NewReader(data)); err != nil { 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)) log.Errorx("dsn: dkim sign for domain, returning unsigned dsn", err, mlog.Field("domain", fd))
} else { } else {
data = append([]byte(dkimHeaders), data...) data = append([]byte(dkimHeaders), data...)
} }
break
} }
return data, nil return data, nil