Hi all,

a while ago we introduced obfuscated message-id headers (see bugzilla #738155 
and related messages in the balsa list).

The message-id now is basically a base64-encoded hash value, which may contain 
the '+' and '/' characters explicitly allowed by RFC 5322.  However, I noticed 
that if a DSN is requested, some MTA's seem to use this message-id verbatim as 
ENVID parameter (see RFC 3461).  In this parameter, though, the '+' character 
is /not/ allowed and must be escaped.  As a result, the receiving MTA /may/ 
reject the message if the ENVID contains an unescaped +.

Although this is a bug in the sending MTA, IMO it would be better to adjust the 
way the message-id is created.  The attached patch uses the first 240 bits (30 
bytes) of the random hash to create a somewhat formatted, base32-encoded 
message-id (see e.g. in this message).

Opinions?

I wish you all a merry Christmas!

Cheers,
Albrecht.
diff --git a/libbalsa/send.c b/libbalsa/send.c
index d38a00b..01487ce 100644
--- a/libbalsa/send.c
+++ b/libbalsa/send.c
@@ -1953,6 +1953,18 @@ libbalsa_message_postpone(LibBalsaMessage * message,
 }
 
 
+static inline gchar
+base32_char(guint8 val)
+{
+	val &= 0x1f;
+	if (val <= 25) {
+		return val + 'A';
+	} else {
+		return val + '2' - 26;
+	}
+}
+
+
 /* Create a message-id and set it on the mime message.
  */
 static void
@@ -1970,6 +1982,8 @@ libbalsa_set_message_id(GMimeMessage * mime_message)
     guint8 buffer[32];
     gsize buflen;
     gchar *message_id;
+    guint8 *src;
+    gchar *dst;
 
     g_mutex_lock(&mutex);
     if (rand == NULL) {
@@ -1994,15 +2008,28 @@ libbalsa_set_message_id(GMimeMessage * mime_message)
     g_hmac_unref(msg_id_hash);
     g_mutex_unlock(&mutex);
 
-    /* create a msg id string
-     * Note: RFC 5322, sect. 3.6.4 explicitly allows the form
-     *    dot-atom-text "@" dot-atom-text
-     * where dot-atom-text may include all base64 (RFC 1421) chars,
-     * including '+' and '/' */
-    message_id = g_base64_encode(buffer, buflen);
-    memmove(message_id + 23, message_id + 22, strlen(message_id) - 23);
-    message_id[22] = '@';
-
+    /* create a msg id string as base32-encoded string from the first
+     * 30 bytes of the hashed result, and separate the groups by '.'
+     * or '@' */
+    message_id = dst = g_malloc0(54U);	/* = (32 / 5) * 9 */
+    src = buffer;
+	while (buflen >= 5U) {
+		*dst++ = base32_char(src[0] >> 3);
+		*dst++ = base32_char((src[0] << 2) + (src[1] >> 6));
+		*dst++ = base32_char(src[1] >> 1);
+		*dst++ = base32_char((src[1] << 4) + (src[2] >> 4));
+		*dst++ = base32_char((src[2] << 1) + (src[3] >> 7));
+		*dst++ = base32_char(src[3] >> 2);
+		*dst++ = base32_char((src[3] << 3) + (src[4] >> 5));
+		*dst++ = base32_char(src[4]);
+		src = &src[5];
+		buflen -= 5U;
+		if (dst == &message_id[(54U / 2U) - 1U]) {
+			*dst++ = '@';
+		} else if (buflen >= 5U) {
+			*dst++ = '.';
+		}
+	}
     g_mime_message_set_message_id(mime_message, message_id);
     g_free(message_id);
 }

Attachment: pgp8wqRJoSZBq.pgp
Description: PGP signature

_______________________________________________
balsa-list mailing list
[email protected]
https://mail.gnome.org/mailman/listinfo/balsa-list

Reply via email to