~sircmpwn/aerc

widgets/compose: Generate Message ID with domain name from address v1 PROPOSED

j.r: 1
 widgets/compose: Generate Message ID with domain name from address

 1 files changed, 25 insertions(+), 3 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/aerc/patches/24976/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] widgets/compose: Generate Message ID with domain name from address Export this patch

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
-- 
2.33.0