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].
This sound resonable, yes, but then we would also need to update
go-message to the latest version. I don't know the codebase enough to
tell if this might break something.
I don't think it will break anything. I just ran an experiment against
the tip of aerc:
$ go mod edit -replace github.com/emersion/go-message=github.com/emersion/go-message@latest
$ go mod tidy
Builds fine and starts right up.
Even if the latest version of go-message did have a breaking API, it is
still worth discussing the possibility of upgrading dependencies to get
security improvements in addition to any performance enhancements or
fancy new features that may be useful.
Connor
j.r
Connor
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
--
2.33.0