This patch changes mutt_gen_msgid (and related) to allow use of the fqdn of the From address when generating the @ portion of the Message-ID.
I use mutt to send email from more than one mail domain. I found that some MTAs reject emails where fqdn of the Message-ID does not have a reverse look-up, returning the error: <user>@*sbcglobal.net*: 550 5.7.1 Connections not accepted from servers without a valid sender domain.alph758 Fix reverse DNS for <ip address> So far, I've only run across it with ATT-related domains. Unfortunately the only solution is to change the `hostname` variable in muttrc(5) and resend. (And yes, checking reverse look-up on the Message-ID fqdn is nutty.) With this change, and the addition of the "%F" sequence, the user can choose between the node `hostname` (%f), or the fqdn of the from address (%F) when generating the Message-ID. The heart of the change is in mutt_gen_msgid. It now accepts a "From" parameter which it parses to extract the fqdn. Lastly, the patch updates the documentation and changes the default message_id_format from "<%z@%f>", to "<%z@%F>" so that Message-IDs are always generated using the fqdn of the From address. That last change makes a certain sense to me, as it ensures that all outbound messages will have a Message-ID associated with the sending domain rather than the MUA host, but I wouldn't complain if were rejected since users can still set it in muttrc(5). The patch was developed and tested on OpenBSD against the port of version 2.1.3. The patch was then applied and tested against commit 543e115132b32571ff98d2e89a82cc0a5e3110d4 (2021-11-15). Thanks, --Aaron diff --git a/init.h b/init.h index 0d920fcd..5e6cedee 100644 --- a/init.h +++ b/init.h @@ -2185,7 +2185,7 @@ struct option_t MuttVars[] = { { "msg_format", DT_SYN, R_NONE, {.p="message_format"}, {.p=0} }, /* */ - { "message_id_format", DT_STR, R_NONE, {.p=&MessageIdFormat}, {.p="<%z@%f>"} }, + { "message_id_format", DT_STR, R_NONE, {.p=&MessageIdFormat}, {.p="<%z@%F>"} }, /* ** .pp ** This variable describes the format of the Message-ID generated @@ -2210,6 +2210,7 @@ struct option_t MuttVars[] = { ** .dt %c .dd step counter looping from ``A'' to ``Z'' ** .dt %d .dd current day of the month (GMT) ** .dt %f .dd $$hostname + ** .dt %F .dd From hostname (after @ in from address) ** .dt %H .dd current hour using a 24-hour clock (GMT) ** .dt %m .dd current month number (GMT) ** .dt %M .dd current minute of the hour (GMT) diff --git a/messageid.c b/messageid.c index e4ac4410..2ab63288 100644 --- a/messageid.c +++ b/messageid.c @@ -30,6 +30,7 @@ typedef struct msg_id_data time_t now; struct tm tm; const char *fqdn; + const char *from_fqdn; } MSG_ID_DATA; static const char *id_format_str (char *dest, size_t destlen, size_t col, @@ -107,12 +108,16 @@ static const char *id_format_str (char *dest, size_t destlen, size_t col, case 'f': mutt_format_s (dest, destlen, fmt, id_data->fqdn); break; + + case 'F': + mutt_format_s (dest, destlen, fmt, id_data->from_fqdn); + break; } return (src); } -char *mutt_gen_msgid (void) +char *mutt_gen_msgid (const char *from) { MSG_ID_DATA id_data; BUFFER *buf, *tmp; @@ -124,9 +129,17 @@ char *mutt_gen_msgid (void) if (!(id_data.fqdn = mutt_fqdn(0))) id_data.fqdn = NONULL(Hostname); + /* from should be a fully-formatted email address, + * nevertheless, handle cases where the caller + * sends just the fqdn or NULL. */ + if (!from) + id_data.from_fqdn = id_data.fqdn; + else if (!(id_data.from_fqdn = strchr (from, '@') + 1)) + id_data.from_fqdn = from; + fmt = MessageIdFormat; if (!fmt) - fmt = "<%z@%f>"; + fmt = "<%z@%F>"; buf = mutt_buffer_pool_get (); mutt_FormatString (buf->data, buf->dsize, 0, buf->dsize, diff --git a/protos.h b/protos.h index fae28c99..f85e1862 100644 --- a/protos.h +++ b/protos.h @@ -151,7 +151,7 @@ void mutt_buffer_expand_multi_path_norel (BUFFER *src, const char *delimiter); void mutt_buffer_remove_path_password (BUFFER *dest, const char *src); char *mutt_find_hook (int, const char *); char *mutt_gecos_name (char *, size_t, struct passwd *); -char *mutt_gen_msgid (void); +char *mutt_gen_msgid (const char *); char *mutt_get_body_charset (char *, size_t, BODY *); const char *mutt_get_name (ADDRESS *); char *mutt_get_parameter (const char *, PARAMETER *); diff --git a/sendlib.c b/sendlib.c index 72f86e68..6334a3aa 100644 --- a/sendlib.c +++ b/sendlib.c @@ -2845,7 +2845,7 @@ void mutt_prepare_envelope (ENVELOPE *env, int final) mutt_set_followup_to (env); if (!env->message_id) - env->message_id = mutt_gen_msgid (); + env->message_id = mutt_gen_msgid (env->from->mailbox); } /* Take care of 8-bit => 7-bit conversion. */ @@ -2908,7 +2908,7 @@ static int _mutt_bounce_message (FILE *fp, HEADER *h, ADDRESS *to, const char *r fprintf (f, "Resent-Date: %s\n", mutt_b2s (date)); mutt_buffer_pool_release (&date); - msgid_str = mutt_gen_msgid(); + msgid_str = mutt_gen_msgid(resent_from); fprintf (f, "Resent-Message-ID: %s\n", msgid_str); fputs ("Resent-To: ", f); mutt_write_address_list (to, f, 11, 0);