From 57292f268a961e559618d0b5007dbda4df33f00c Mon Sep 17 00:00:00 2001 From: "j.r" Date: Sat, 4 Sep 2021 15:14:42 +0200 Subject: widgets/compose: Generate Message ID with domain name from address go-messages GenerateMessageID does generate the Message ID based on the hostname of the local machine. This is ok in this context because the lib does not know really anything of the surroundings. But aerc does know about the sender domain and could use this instead of the hostname. This also aligns with the recommendation of RFC4322 to use a unique domain name, to ensure the uniqueness of the whole Message ID [1]. A side effect of this change is that it also improves the score of some spam filters a bit, if an E-Mail has a fully qualified domain name after the @. This patch fixes https://todo.sr.ht/~sircmpwn/aerc2/526 [1] https://www.rfc-editor.org/rfc/rfc5322.html#section-3.6.4 --- widgets/compose.go | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/widgets/compose.go b/widgets/compose.go index 01c6281..91599c6 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -3,15 +3,18 @@ package widgets import ( "bufio" "bytes" + "encoding/binary" "fmt" "io" "io/ioutil" + "math/rand" "mime" "net/http" "net/textproto" "os" "os/exec" "path/filepath" + "strconv" "strings" "time" @@ -381,9 +384,24 @@ func (c *Composer) PrepareHeader() (*mail.Header, error) { // control headers not normally set by the user // repeated calls to PrepareHeader should be a noop if !c.header.Has("Message-Id") { - err := c.header.GenerateMessageID() - if err != nil { - return nil, err + if c.header.Has("From") { + // generate the Message-Id our self, to include a FQDN, code is based on the GenerateMessageID of go-message + now := uint64(time.Now().UnixNano()) + + nonceByte := make([]byte, 8) + if _, err := rand.Read(nonceByte); err != nil { + return nil, err + } + nonce := binary.BigEndian.Uint64(nonceByte) + + fromAddresses, err := c.header.AddressList("From") + if err != nil { + return nil, err + } + domain := strings.Split(fromAddresses[0].Address, "@")[1] + + msgID := fmt.Sprintf("%s.%s@%s", base36(now), base36(nonce), domain) + c.header.Set("Message-Id", "<"+msgID+">") } } if !c.header.Has("Date") { @@ -392,6 +410,10 @@ func (c *Composer) PrepareHeader() (*mail.Header, error) { return c.header, nil } +func base36(input uint64) string { + return strings.ToUpper(strconv.FormatUint(input, 36)) +} + func (c *Composer) WriteMessage(header *mail.Header, writer io.Writer) error { if err := c.reloadEmail(); err != nil { return err -- cgit v1.2.3