Paul
Paul

Reputation: 826

Test "Received" email header in sieve

Here is an example of how I have configured sieve to forward any mail sent to [nameA|nameB|nameC]@example.org to my private email address.

if address :localpart :is ["To","Cc","Bcc"]
 ["nameA", "nameB", "nameC"] {
    redirect "<my private email address>";
    stop;
}

Sometimes though, email is not forwarded because the address that it was sent to is tucked away somewhere in a "Received" header.

Received: from ###server### ([###ip_address###])
    by ###server### with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256)
    (Exim 4.84)
    (envelope-from <###email_address###>)
    id 1alDM0-0000yT-60
    for [email protected]; Wed, 30 Mar 2016 12:28:00 +0200

Is there an effective way to catch these emails in the sieve rule, too?

Upvotes: 6

Views: 2626

Answers (3)

enigmaticPhysicist
enigmaticPhysicist

Reputation: 1729

Just test the header like one would test any other header.

So, one is matching for either of the substrings for [email protected], for [email protected], etc. in any Received header. Here's what that looks like in sieve:

require ["fileinto"];

if header :contains "Received" ["for [email protected]", "for [email protected]", "for [email protected]"] {
    redirect "<my private email address>";
    stop;
}

:contains does the substring matching. There is also glob / wildcard matching, with :matches. See https://www.ietf.org/rfc/rfc5228.txt page 13 for more.

Emails often have many of these Received headers—one per SMTP server in the chain from source to destination. That's OK, though, because the header test succeeds when any Received header matches any substring in the list. For more on it, see page 28 of the same RFC.

Upvotes: 1

user65839
user65839

Reputation:

You have an XY Problem here. What you actually want to do here is filter based on the address being delivered to, not the address in the headers. (As unintuitive as it may be, the address in the headers may have nothing to do with the address it's being delivered to, which is how Bcc can work at all.)

The command to test against the actual SMTP envelope is envelope.

require "envelope";
if envelope :localpart :is "to" ["nameA", "nameB", "nameC"] {
    redirect "<my private email address>";
    stop;
}

This will handle all mail being delivered to those names, regardless of whether they show up in the mail headers or not.

Upvotes: 4

Zilon
Zilon

Reputation: 9

With the help of the sieves' index feature you can parse the recipient address out of the Received headers.

For BCC sorting I typically do something like this:

require ["fileinto", "envelope", "variables", "mailbox", "index", "subaddress"];
...
if header :index 3 :matches "Received" "*<*@example.com>*" {   
  set :lower "foldername" "${2}";
  fileinto :create "inbox.${foldername}";
} elsif header :index 2 :matches "Received" "*<*@example.com>*" {       
  set :lower "foldername" "${2}"; 
  fileinto :create "inbox.${foldername}";
}
...

In the Received headers of the mails I receive the adress is set in angle brackets and that's why I've chosen the pattern in the example above.

Additionally, sometimes the number of Received headers varies thus I test at least for two different ones.

Upvotes: 0

Related Questions