[RFC PATCH] CLI/reply: Remove Received by domain From detection

Subject: [RFC PATCH] CLI/reply: Remove Received by domain From detection

Date: Fri, 19 Apr 2024 20:35:53 -0500

To: notmuch@notmuchmail.org


From: Liam Hupfer

This creates too many false positives in a world with huge free mail
providers. Using Gmail as the foremost example: Many people have Gmail
accounts. If a user with a secondary Gmail account imports mail from a
list archive (meaning none of their personal addresses will be present
in the messages) and then uses a Notmuch client to reply to a message
that was sent by a Gmail user, their own secondary Gmail account will be

It gets worse with organizations who pay Microsoft to host their email.
If a user imports a message from ubc.ca and replies to it, their
secondary outlook.com address will be used because ubc.ca email
currently happens to be provided by Microsoft through their outlook.com
servers. For users unfamiliar with the internal details of email
protocols, this behavior is inscrutable.

In these scenarios, it makes more sense to fall back to the user’s
configured primary address, particularly because the primary address
/will/ be used when replying to any messages that do not happen to
involve a sender who uses the same email provider as one of the user’s
secondary addresses. To new users who aren’t familiar with the internal
details of notmuch-reply, it will appear as though their secondary
addresses are used intermittently when composing replies to imported
mail for no apparent reason.

This function theoretically adds value for users with multiple addresses
who want to use a secondary address when replying to imported mail from
a list hosted on the same infrastructure as the secondary address (e.g.
someone wants to use their gnu.org email address to reply “with their
GNU hat on” to imported messages from gnu.org lists). But such users are
also more likely to be outright subscribed to such lists anyway.
Therefore, it seems preferable to reduce confusion for the much more
common use case by making From address discovery “dumber” but more

Hi Notmuch developers,

I have secondary Gmail and Outlook.com accounts and ran into this
confusing behavior. I’m by no means an email expert and could definitely
be missing use cases for the original behavior, so let me know what you

Also, I made the tests pass in the lowest-effort way possible; if the
patch makes sense, let me know if you prefer something else.

 notmuch-reply.c            | 74 --------------------------------------
 test/T280-from-guessing.sh |  2 +-
 2 files changed, 1 insertion(+), 75 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index 44297251..bce38b23 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -144,15 +144,6 @@ user_address_in_string (const char *str, notmuch_database_t *notmuch)
     return address_match (str, notmuch, USER_ADDRESS_IN_STRING);
-/* Do any of the addresses configured as one of the user's "primary"
- * or "other" addresses contain the given string. If so, return the
- * matching address, NULL otherwise. */
-static const char *
-string_in_user_address (const char *str, notmuch_database_t *notmuch)
-    return address_match (str, notmuch, STRING_IN_USER_ADDRESS);
 /* Is the given address configured as one of the user's "primary" or
  * "other" addresses. */
 static bool
@@ -396,69 +387,6 @@ guess_from_in_received_for (notmuch_database_t *notmuch, const char *received)
     return user_address_in_string (ptr, notmuch);
- * Parse all the " by MTA ..." parts in received headers to guess the
- * email address that this was originally delivered to.
- *
- * Extract just the MTA here by removing leading whitespace and
- * assuming that the MTA name ends at the next whitespace. Test for
- * *(by+4) to be non-'\0' to make sure there's something there at all
- * - and then assume that the first whitespace delimited token that
- * follows is the receiving system in this step of the receive chain.
- *
- * Return the address that was found, if any, and NULL otherwise.
- */
-static const char *
-guess_from_in_received_by (notmuch_database_t *notmuch, const char *received)
-    const char *addr;
-    const char *by = received;
-    char *domain, *tld, *mta, *ptr, *token;
-    while ((by = strstr (by, " by ")) != NULL) {
-	by += 4;
-	if (*by == '\0')
-	    break;
-	mta = xstrdup (by);
-	token = strtok (mta, " \t");
-	if (token == NULL) {
-	    free (mta);
-	    break;
-	}
-	/*
-	 * Now extract the last two components of the MTA host name as
-	 * domain and tld.
-	 */
-	domain = tld = NULL;
-	while ((ptr = strsep (&token, ". \t")) != NULL) {
-	    if (*ptr == '\0')
-		continue;
-	    domain = tld;
-	    tld = ptr;
-	}
-	if (domain) {
-	    /*
-	     * Recombine domain and tld and look for it among the
-	     * configured email addresses. This time we have a known
-	     * domain name and nothing else - so the test is the other
-	     * way around: we check if this is a substring of one of
-	     * the email addresses.
-	     */
-	    *(tld - 1) = '.';
-	    addr = string_in_user_address (domain, notmuch);
-	    if (addr) {
-		free (mta);
-		return addr;
-	    }
-	}
-	free (mta);
-    }
-    return NULL;
  * Get the concatenated Received: headers and search from the front
  * (last Received: header added) and try to extract from them
@@ -486,8 +414,6 @@ guess_from_in_received_headers (notmuch_message_t *message)
 	return NULL;
     addr = guess_from_in_received_for (notmuch, sanitized);
-    if (! addr)
-	addr = guess_from_in_received_by (notmuch, sanitized);
     talloc_free (sanitized);
diff --git a/test/T280-from-guessing.sh b/test/T280-from-guessing.sh
index b8718232..f3445f04 100755
--- a/test/T280-from-guessing.sh
+++ b/test/T280-from-guessing.sh
@@ -86,7 +86,7 @@ add_message '[from]="Sender <sender@example.com>"' \
 	    '[body]="from guessing test"'
 output=$(notmuch reply id:${gen_msg_id})
-test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@otherdomain.org>
+test_expect_equal "$output" "From: Notmuch Test Suite <test_suite@notmuchmail.org>
 Subject: Re: notmuch-reply-test
 To: Sender <sender@example.com>, mailinglist@notmuchmail.org
 In-Reply-To: <${gen_msg_id}>

base-commit: cd89065dc36e36b22a2a53832d2cac9b06fba41c

notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-leave@notmuchmail.org