Authenticating email through SMTP or DKIM - perl

I'm using Perl with the
Mime::Lite module
to send email to my subscribed mailing list using
DomainKeys Identified Mail (DKIM)
and
Sender Policy Framework (SPF)
record:
use MIME::Lite;
use Net::SMTP;
my $host = 'mail.domain.com';
my $user = 'user#domain.com';
my $pass = 'password1234';
MIME::Lite->send('smtp', $host, AuthUser => $user, AuthPass => $pass);
my $msg = MIME::Lite->new(
From => $from,
To => $to,
Subject => $subject_enc,
Type => 'text/plain; charset=UTF-8',
Encoding => 'quoted-printable',
Data => 'Hello everyone!'
);
$msg->send;
This works just fine, but the DKIM signature fails in Gmail (and presumably others).
However, when I send email without SMTP authentication:
use MIME::Lite;
my $msg = MIME::Lite->new(
From => $from,
To => $to,
Subject => $subject_enc,
Type => 'text/plain; charset=UTF-8',
Encoding => 'quoted-printable',
Data => 'Hello everyone!'
);
$msg->send;
The DKIM passes fine.
So my question is: if I have successfully implemented both DKIM and SPF records on all my outgoing email, is it even necessary to use SMTP authentication to verify the sender of the email, or is piping to Sendmail with the appropriate headers sufficient to ensure best chance of delivery?

Local authentication doesn't add much to the credibility of your messages, but also there's no harm in it. It will show up in your Received headers either way, and there's a distant possibility you might be marked down by spam filters for it (they'd probably be more interested in whether any hops were unencrypted, which is independent of auth).
That you used auth shouldn't make any difference to DKIM - but what will make a difference is where (and if) your DKIM signing takes place - for example if your local mail server signs but your remote one doesn't. Does the Mail::Lite package do DKIM signing itself? Or are you relying on your servers to do it? Your headers in received messages will show you what has been signed where, and they may also give you some clues about what exactly is wrong with your DKIM signature - it would be useful if you added gmail's headers to your question.
A separate concern is performance - submitting via a sendmail binary is relatively inefficient - all sendmail binaries do is open a synchronous SMTP connection to localhost anyway, so you may as well do it directly - this is what postfix recommends.

Related

Getting email provider from email address

I'm trying to get the email provider (ex: gmail,outlook,yahoo) from any email address so that i can use specific smtp settings to avoid my messages being listed as spam.
My current approach is parsing the mail server potion of the email address and using that as the identifier but email providers have multiple mail servers (ex: outlook has outlook.com but also live.ca).
Any suggestions of a simple approach to identifying the mail provider? If there is any method using PHP that would be especially desirable. Any help?
You can use a map for mapping the mail domain name (that you obtain after parsing the e-mail address) to the mail provider:
$providerMap = array(
"gmail" => "Gmail"
"outlook" => "Outlook"
"live" => "Outlook"
# etc...
);
Then, you can use it like this:
$providerDomain = getDomain($emailAddress); // assuming getDomain() is the function that parses an email address and returns
echo "The provider is: $providerMap[$providerDomain]"
P.S.: You may want to think about how to handle the case where the email address domain name doesn't match any provider. You can:
Throw an exception/display an error message
Add a functionality allowing an authorised user to add a new provider (i.e. for adding a new entry in the map)
...

Postfix Perl mailing via PostDrop

I'm trying to inject an email directly into the postfix queue using a perl module Mail::Postfix::Postdrop which ultilises a postfix method of allowing messages to be written directly to the postdrop directory.
There is a small amount of documentation which has enabled me to send a message successfully, however, I am confused to how I am able to set a subject and message body. An attempt to set the variable $message does little to nothing.
I must admit, I'm an apprentice to Perl at best, I would appreciate any help.
#Code which successfully sends an email:
use Mail::Postfix::Postdrop 'inject';
$message = 'test message';
inject $message, Sender => 'postmaster#mydomain.com',
Recipients => [ qw(email#someotherdomain.com) ];
Some relavant documentation:
http://annocpan.org/~PMAKHOLM/Mail-Postfix-Postdrop-0.3/lib/Mail/Postfix/Postdrop.pm
In email messages "headers" section is separated from "body" section by empty line. Just change your $message to:
$message = "Subject: This is my subject!\n\nAnd this is my message";
and you should see that you've set subject and message text. Note "\n\n", which creates empty line (double quotes are used to allow \n interpolation in $message).
Note that Mail::Postfix::Postdrop claims it accepts Email::Abstract object as a message, so you might consider using Email::Simple (or other Email::Abstract supporting class) to create your messages.

Swiftmailer won't send mail, but mail() will

PHP's mail() function sends mail fine, but Swiftmailer's Swift_MailTransport doesn't work!
This works:
mail('user#example.com', 'test '.date('H:i:s'), '');
But this does not:
$transport = Swift_MailTransport::newInstance('');
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance('test '.date('H:i:s'))
->setFrom('user#example.com')
->setTo('user#example.com')
->setBody('Testing one two three');
$result = $mailer->send($message);
(The user#example.com is replaced by a valid email address in my test code.)
The mail logs for both events look very similar in both cases, and it appears that mail is being sent in the latter.
Could there be something about the message constructed by Swiftmailer that is causing it to be blocked by a spam filter?
(By the way, I have tried using the SMTP transport, with no luck; I figured that since mail() works correctly, it would be trivial to switch to Swiftmail's Mail transport...)
Which mail server are you using(like your web server or gmail,yahoo..)
this is for gmail SMTP,
$transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, "ssl")
->setUsername($login_id)
->setPassword($password)
;
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance('test '.date('H:i:s'))
->setFrom('user#example.com')
->setTo('user#example.com')
->setBody('Testing one two three');
$result = $mailer->send($message);
if mail() function works, then SwiftMailer should also work.
Hope it worked for you, and helped you.

Sending Mail Through Perl

I am using the below code to send an email
#!/usr/bin/perl
sub BEGIN {
unshift (#INC,'/opt/dev/common/mds/perlLib');
}
use Mail::Sender;
$sender = new Mail::Sender
{smtp => 'xxx.xxx.x.xx', from => 'abc#xyz.xom'};
$sender->MailFile({to => 'abc#xyz.xom',
subject => 'Here is the file',
msg => "I'm sending you the list you wanted."});
$sender->Close;
But, it is not sending the mail at all. What is wrong in my code?
I don't use that module because MIME::Entity works so much better, but from working with mail, I can tell you that you are getting ahead of yourself, and making assumptions rather than deductions.
perldoc on that module shows several methods -- and MailFile is for attaching and sending files. If it fails when sending a message without an attached file, I'd have to say I'm not surprised. Has that worked anywhere else?
Were you able to make MailMsg() work? If you cannot, (the syntax is very similar but with fewer things to go wrong), then you may have a problem with connecting to server. From the xxx.xxx.xxx.xxx bit, I'd have to assume you're using an ip address. Try a hostname. Also, set on_errors to die() or maybe warn(), and see if you can trap the error. Most mail attempts fail during the connect to the server/creation of the object -- then the sending attempt will by definition fail, but often without telling you why.
If you cannot connect, make sure that you aren't needing to authenticate to your server.

Using CakePHP's Email component

I try to send a simple Email via CakePHP's Email Component. I'm using following code from the cookbook documentation:
$this->Email->from = 'Irgendjemand <irgendjemand#example.com>';
$this->Email->to = 'Irgendjemand Anderes <irgendjemand.anderes#example.com>';
$this->Email->subject = 'Test';
$this->Email->send('Dies ist der Nachrichtenrumpf!');
The send()-method does only return a boolean value with the value false - but no error or warning occurs.
Does somebody have a solution for that?
Have you tried changing the delivery options? There are three options: mail, smtp and debug.
$this->Email->delivery = 'debug';
$this->Email->send('test message');
debug($this->Session->read('Message.email'));
You can debug with EMail. Set the delivery to debug and the email message will be set to Session.message:
if (Configure::read('debug') > 1) {
$this->Email->delivery = 'debug';
}
$ret = $this->Email->send();
if (Configure::read('debug') > 1) {
pr($this->Session->read('Message.email'));
}
Which OS are you on? If Windows, this note may be of interest:
Note: The Windows implementation of mail() differs in many ways from the Unix implementation.
...
As such, the to parameter should not be an address in the form of
"Something <someone#example.com>". The mail command may not parse this properly while talking with the MTA.
Secondly, it may just be the case that no mail server will accept outgoing mail from your local machine due to spam protection. I have often seen that the same mail() function will not work locally, but works fine once uploaded to a trustworthy server. You could try to use an authenticated mail relay in that case (SMTP).