Test "Received" email header in sieve - email

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 nameA#example.org; Wed, 30 Mar 2016 12:28:00 +0200
Is there an effective way to catch these emails in the sieve rule, too?

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.

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.

Related

How to change recipient of a VACATION autoresponder mail to one in sender's mail header section [Reply-to] purely in Sieve Language?

I need to set an autoresponder that will send a message like "We got You mail! We will get back to you ASAP". The problem is that the sender of customer email is not customer itself (i.e. customer#privatemail.com), but some global mail (i.e. customerservice#marketplace.com) that contains customer private mail in the header section [Reply-to].
This is a hosted server with installed RoundCube. I can only use Sieve filters to create an autoresponder.
rule:[Autoresponder]
if allof (
header :contains "from" "#marketplace.pl",
{
vacation text:
We got You mail! We will get back to you ASAP!
.
;
}
I need to read the value of the header [Reply-To] section, set the recipient of autoresponder mail to that value and send a VACATION message. Only in Sieve language.

Send email to address alternate from "To:"

I am implementing a sort of dynamic mailing-list system in Rails. I am looking to basically send an email and have the recipient receive it in this form:
From: person#whosentthis.com
To: mailing-list#mysite.com
<body>
Basically, the challenge is how do I send an email to an address while defining a different To: header so that they can easily reply to the mailing list or just the original sender?
Mail vs. Envelope
In emails as in physical mails (paper sheet in paper envelope), the recipient on the envelope may differ from the recipient on the letter sheet itself.
As the mailman would only consider the envelope's recipient, so do mail servers.
That means, one actually can tell the smtp service to send and email to a recipient different than the one listed in the To: field of the emails header.
Trying This Out Manually
You can try this out, manually, for example, by using the sendmail command of postfix.
# bash
sendmail really_send_to_this_address#example.com < mail.txt
where
# mail.txt
From: foo#example.com
To: this_will_be_seen_in_the_to_field_in_email_clients#example.com
Subject: Testmail
This is a test mail.
This will deliver the email to really_send_to_this_address#example.com, not to this_will_be_seen_in_the_to_field_in_email_clients#example.com, but the latter will be shown in the recipient field of the mail client.
Specifying the Envelope_to Field in Rails
The ActionMailer::Base internally uses the mail gem. Currently, Apr 2013, there is a pull request, allowing to specify the envelope_to field on a message before delivery.
Until this is pulled, you can specify the fork in the Gemfile.
# Gemfile
# ...
gem 'mail', git: 'git://github.com/jeremy/mail.git'
You need to run bundle update mail after that, and, depending on your current rails version, maybe also bundle update rails in order to resolve some dependency issues.
After that, you can set the envelope recipient of a mail message like this:
# rails
message # => <Mail::Message ...>
message.to = [ "this_will_be_seen_in_the_to_field_in_email_clients#example.com" ]
message.smtp_envelope_to = [ "really_send_to_this_address#example.com" ]
message.from = ...
message.subject = ...
message.body = ...
message.deliver
Documentation
https://github.com/mikel/mail/pull/477
http://rubydoc.info/github/jeremy/mail/master/Mail/Message#smtp_envelope_to%3D-instance_method
https://github.com/mikel/mail
Why not use the BCC header for this? Put person#whoshouldreceivethis.com into BCC and mailing-list#mysite.com into TO.
Clearification:
There is no technical solution for this. The email headers do what they do, you can't influence them in that once the email is on the way.
I am sure, though, you can find a combined use of TO, CC, BCC and REPLY-TO that gives you what you want.

In SMTP, must the RCPT TO: and TO: match?

When sending an email, the recipient list is given during the SMTP dialogue through RCTP TO: command. Later, in DATA command, header fields like 'To', 'Cc','bcc' are indicated. Does this RCPT TO list of recipients have to match with the headers indicated in DATA command?
Also, if the recipient is not indicated in RCPT TO, but in the To field of email header, is it going to be delivered to the recipient not in RCPT TO?
No, they don't have to match. When the message is sent, the SMTP Server (aka Message Transfer Agent or MTA) is creating a so called SMTP envelope which contains the recipients and the sender of the message (see RFC5321):
SMTP transports a mail object. A mail object contains an envelope and content. The SMTP envelope is sent as a series of SMTP protocol
units (described in Section 3). It consists of an originator
address (to which error reports should be directed), one or more
recipient addresses, and optional protocol extension material.
It is, actually, quite often that the RCPT TO: Command has more recipients that the header of the message - one common case is the usage of "blind copies" bcc: (see RFC5321):
Addresses that do not appear in the message header section may appear
in the RCPT commands to an SMTP server for a number of reasons. The
two most common involve the use of a mailing address as a "list
exploder" (a single address that resolves into multiple addresses) and
the appearance of "blind copies".
Does this RCPT TO list of recipients have to match with the headers
indicated in DATA command?
Nope.
if the recipient is not indicated in RCPT TO, but in the To field of
email header, is it going to be delivered to the recipient not in RCPT
TO ?
The RCPT. Here's a (modified) transcript from my own SMTP client where I do just what you ask:
CLIENT: MAIL FROM:<myaccount#gmail.com>
SERVER: 250 2.1.0 OK
CLIENT: RCPT TO:<myaccount#gmail.com>
SERVER: 250 2.1.5 OK
CLIENT: DATA
SERVER: 354 Go ahead
CLIENT: Subject: Test email
CLIENT: From:'John Doe'<fakeaccount#gmail.com>
CLIENT: To:'John Doe'<fakeaccount#gmail.com>
CLIENT: This is a test...
CLIENT: .
The message was successfully sent to "myaccount#gmail.com".
SMTP protocol (RFC 2821) states the following:
When RFC 822 format [7, 32] is being used, the mail data include the
memo header items such as Date, Subject, To, Cc, From. Server SMTP
systems SHOULD NOT reject messages based on perceived defects in the
RFC 822 or MIME [12] message header or message body.
And this:
The DATA command can fail at only two points in the protocol
exchange:
If there was no MAIL, or no RCPT, command, or all such commands
were rejected, the server MAY return a "command out of sequence"
(503) or "no valid recipients" (554) reply in response to the DATA
command. If one of those replies (or any other 5yz reply) is
received, the client MUST NOT send the message data; more
generally, message data MUST NOT be sent unless a 354 reply is
received.
From these statements, the headers and RCPT TO: command content does not have to match (altough they should match), and not using RCPT TO: MAY result in an error to prevent proceeding with DATA command.

Exim: Forward Based on Recipient in bcc

Currently I am filtering incoming mails by a .forward in the following way:
if $header_to: matches "(office|info)#domain.com" then
save Maildir/.office/
endif
if $header_to: matches "whatever#domain.com" then
save Maildir/.whatever/
endif
So I have a mail account, which receives mails for different addresses. Basically I want them to land in different subdirs based on the address the mail was sent to.
This works for mails where the recipient is in the to-header, but does not work if the recipient was in the bcc.
When a mail is received which was sent with the bcc-header, only the envelope-to-header matches the real address the mail is delivered to and it is mentioned in a Received-header
Envelope-to: office#domain.com
Received: from mail.other.domain ([1.1.1.1])
by mail.domain.com with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)
(Exim 4.71)
(envelope-from <sender#other.domain>)
id 1RO5xc-0001TF-Qj
for office#domain.com; Wed, 09 Nov 2011 12:04:57 +0100
...
To: can_be_anything#whatever.com
I already tried:
if $header_envelope-to: matches ...
but this does not work, mails are not filtered at all even when sent with To-header (looks like the Envelope-To-header is not available in forward-files). Should I try to parse the (multiple) Received-headers?
How can I move mails into a subdir of the recipient based on the real recipient address?
looks like I finally found the answer.
if $original_local_part matches "office|info" then
save Maildir/.office/
endif
This checks only the local_part, but afaik could be extended to use the domain, too, with $original_domain (see the doc)
The variable $recipients contains all (to, cc and bcc) recipients. Have you tried it?

when using Zend_mail my emails seem to be treated as spam, send through outlook and there not?

I'm trying to sort out an opt in mailing list system. I understand the basic principles and design required but i'm having an issue with it being picked up as spam.
If i send a html email through outlook through email#domain.com it works fine and is not treated as spam. When i use the Zend_mail object to send mail it sends but is treated as spam on the test emails accounts i'm sending it too.
This is the code im using to send an email item.
//send an email
$mail = new Zend_Mail();
$config = array('auth' => 'login','username' => 'email#domain.com','password' => 'mypassword');
$transport = new Zend_Mail_Transport_Smtp('mail.domain.com', $config);
$mail->setSubject($item->title);
$mail->setFrom("email#domain.com");
$mail->addTo($item->email, $item->forename);
//$mail->setBodyText($item->contentPlain);
$mail->setBodyHtml($item->contentHTML);
$mail->send($transport);
As you can see im using the smtp transport object to authenticate but it still seems to treat this as spam. Anyone with pointers or tips is very much appreciated!!
Header info from the email that is treated as spam:
It seems to contain a couple of client domain names in the header info that i host for people any ideas why that would be the case? I use a shared IP address with about 10 domains on it
Received: (qmail 1436 invoked from network); 14 Aug 2009 16:02:10 +0100
Received: from clientdomain1.co.uk (HELO localhost) (91.192.***.196)
by clientdomain2.info with SMTP; 14 Aug 2009 16:02:10 +0100
Subject: Manchester 2 Day Seminar: Dealing with difficult people
From: events#domain.com
To: Andi <subscriber1#domain.com>
Date: Fri, 14 Aug 2009 15:02:10 +0000
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
MIME-Version: 1.0
"Roll your own mail" is often treated as spam by large hosted email systems. When you use a paid service to send out mass emails, you are paying for those company's agreements with the major email vendors to keep them white-listed.
One thing you can do, though, is to ensure that the account you are sending from exists and the email is being sent from a matching domain (e.g. #foo.com sent from foo.com's smtp server). That is a big red flag for spam filters.
Compare your email and email from outlook. Are any headers missing? Which? Do they seem significant?
Try this to get rid of the last localhost reference:
$protocol = new Zend_Mail_Protocol_Smtp('localhost');
$protocol->connect();
$protocol->helo('mail.yourserver.com'); //**DO THIS**
$transport->setConnection($protocol);