Setting up DomainKeys/DKIM in a PHP-based SMTP client [closed] - php

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
It looks like there are some great libraries out there to do DomainKeys signing of emails on C#/.NET, but I'm having a really hard time finding the same kind of support for PHP. Maybe I'm not looking in the right place?
The only one I found is http://php-dkim.sourceforge.net/; it looks incredibly hacky and supports PHP4 only. Considering how popular PHP is, and how critical DomainKeys are for email classification as non-spam, I'd expect better tools; do you know of any? Any other tricks you'd recommend?
Extra info: I'm using an external SMTP provider because I need to send out thousands of emails per day.

I'd recommend DKIM support at the MTA level so all your server generated email for a given domain is signed by default. (unless you have a really good reason to not sign all server generated email for a domain).
The best starting point in my googling to get DKIM setup on LAMP with dkim-milter and sendmail (on CentOS 5.2 in my case) was Jeff Atwood's post about sending emails through code.
I would agree with him that the first 2 things you should address are reverse PTR record and DKIM signing.
Also very important:
IP address of the box to send email not already being blacklisted.
make sure postmaster#emailsendingdomain.com is a valid email box
if your server generated email needs to appear to come from somewhere else (like a contact form needing to come from name/email provided in a form) follow these guidelines for email headers.
Here is the email ip address blacklist checker that I used.
Those 5 things will solve perhaps 95% of your email deliverability issues.
This Guide for Fedora/dkim-milter/postfix is also very good.
The PHP mail library I use for my app is PHPMailer 5.1 which has DKIM support (and is PHP 5 only), but after doing the research, I decided implementing at the sendmail level was a better solution. As you can see, even the author of PHPMailer 5.1 does not suggest DKIM at the PHP mail library level is the best solution http://dkim.worxware.com/.
Best of luck to you.

This is one that has been on my radar for a while and could not find a definitive answer to the original question in this thread anywhere on the web. I have now been able to implement sending DKIM signed SMTP email with PHP/Pear. Below are the steps required.
I found a modified version of the DKIM from http://www.ra726.net/blog/2010/07/20/sending-email-to-gmail-from-php-without-being-marked-as-spam/ (you can download it via http://www.ra726.net/php-dkim.zip). If you have already implemented DKIM and just need to make it work with SMP mail then all you need from this is the dkim.php file which, as the blog says, is slightly modified to handle headers passed as an array. In my code, I have named it dkimNEW.php.
Ensure you include most headers so that the MTA does not modify the message after you have signed it. In my limited research, the most added headers are the Date and Message-ID headers, thus my header array looks like this: Note: I used this for sending an html email, change to suit! Also, add your domain as the last part of the Message-ID
$headers = array(
'Subject' => $subject,
'From' => $from,
'To' => $to,
'MIME-Version' => '1.0',
'Date' => date('r'),
'Message-ID' => '<'.sha1(microtime(true)).'#yourdomain.com>',
'Content-Type' => 'text/html',
'Content-Transfer-Encoding' => 'quoted-printable',
); // end $headers
You will then get to utilize the modified dkim.php mentioned above to sign your email AND add the signature to the headers array, aka
require 'dkimNEW.php';
$dkim = AddDKIM($headers, $subject, $body);
$headers['DKIM-Signature'] = $dkim;
The rest of the code is the normal code to send email via SMTP with PHP/Pear. The full working code is:
<?php
require_once 'Mail.php';
require_once 'Mail/mime.php';
// set all of the parameters
$subject = 'Test of DKIM';
$from = 'My Name <myname#mydomain.com>';
$to = 'First Recipient <recipient1#domain.com>';
$pbody ='<html><head></head><body><h1>Done! DKIM test</h1>Result, next?</body></html>';
$text = strip_tags($pbody);
// create the headers
$headers = array(
'Subject' => $subject,
'From' => $from,
'To' => $to,
'MIME-Version' => '1.0',
'Date' => date('r'),
'Message-ID' => '<'.sha1(microtime(true)).'#mydomain.com>',
'Content-Type' => 'text/html',
'Content-Transfer-Encoding' => 'quoted-printable',
); // end $headers
// create the message
$mime = new Mail_mime("\n");
$mime->setTXTBody($text);
$mime->setHTMLBody($pbody);
// always call these methods in this order
$body = $mime->get();
$headers = $mime->headers($headers);
require 'dkimNEW.php' ;
$dkim = AddDKIM($headers, $subject, $body);
$headers['DKIM-Signature'] = $dkim;
// create the smtp mail object
$smtp_params = array(
'host' => 'mail.mydomain.com',
'auth' => true,
'username' => 'myUserName',
'password' => 'myPassWord',
); // end $smtp_params
$smtp = Mail::factory('smtp', $smtp_params);
// send the message
$recipients = array('recipient1#domain.com', 'recipient2#domain.com');
$mail = $smtp->send($recipients, $headers, $body);
?>
PS. Just in case you did not notice, replace values with your own!
Therefore, all that is essentially needed to make DKIM to work with SMTP email (or indeed the PHP mail) is to ensure that you specify all the headers that are added to your email by your MTA, then sign the headers, subject and body of the message, and finally include that signed portion with your header.

Have you try : phpMailDomainSigner It support DKIM-Signature and DomainKey-Signature in Object Oriented Style.
Here some example:
// Create mailDomainSigner Object
include_once './lib/class.mailDomainSigner.php';
$mds = &new mailDomainSigner($domain_priv,$domain_d,$domain_s);
$new_data = $mds->sign(
$mail_data,
"Message-ID:Subject:From:Content-Type:MIME-Version:Content-Transfer-Encoding:Received:To:Date",
true,true,false);

A class solely for DKIM which is a spin-off from PHPMailer, but with improvements regarding the respect of the RFC and nice-and-clean code :
https://sourceforge.net/projects/dkim-class-php/
Example :
include_once('dkim.class.php');
$dkim = new DKIM();
$dkim_header = $dkim -> get_DKIM_header($to, $subject, $message, $headers);
mail($to, $subject, $message, $dkim_header.$headers);

Related

pear mail not working

My use of Pear to relay one of our site's users ('sender') email to another user ('recipient') fails because the recipient user always receives the mail in their spam folder. For the explanation below, our website is called "oursite.com."
I have narrowed this down after 2 solid days of lots of experimenting to the "From" part of the 'headers' as follows (for the sake of this example, my name is Sam Hambone and I have no idea how the 'From:' in the title of the email is grabbing my name and using it as described below):
$senderEmail = "IamTheSender#gmail.com";
// this version of the 'from' variable makes the 'From' in the email's title
// look correct, like this: "IamTheSender#gmail.com (IamTheSender#gmail.com)"
// but when the recipient gets the mail, it will ALWAYS go into the 'junk'
// or 'spam' email folder of the recipient's inbox. NOTE: using angle brackets
// instead of parentheses here changes nothing.
$from = $senderEmail . " (" . $senderEmail . ")";
// this second version of 'from' makes the mail arrive correctly
// in the recipient's Inbox and not in their spam/junk folder, but
// the "From:" line in the email's title looks like this:
// "Sam Hambone (IamTheSender#gmail.com)"
$from = $senderEmail;
EDIT: here is what the email's title and headers look like using the 1st version of 'from' above -- in this case I sent an email to myself as the recipient:
'Sender has a question for you, Mr. Recipient!'
Sam Hambone (IamTheSender#gmail.com) << this is wrong -- it's mixing my (recipient)
real name with the sender's email address!!
To: sammyhambone#hotmail.com
From: IamTheSender#gmail.com
Sent: Fri 10/18/13 5:49 PM
To: sammyhambone#hotmail.com (sammyhambone#hotmail.com)
Here is the rest of the code -- this code successfully sends out the email, but by using one of the above versions of the from variable, I either find the email go to the recipient's Junk folder or the 'From:' part in the email's title is screwed up as described above:
$theRecipient = "aLoyalUser#hotmail.com";
$to = $theRecipient . " (" . $theRecipient . ")";
$subject = "the subject is Pear and emailing.";
$body = "Ach, megotts lads, comes the blarney stone."
$host = "smtp.1and1.com";
$port = "25";
$username = "myAuthName#oursite.com";
$password = "12345";
$smtp = Mail::factory('smtp',
array ('host' => $host,
'port' => $port,
'auth' => true,
'username' => $username,
'password' => $password));
$headers['From'] = $from; // one of the two 'from' versions given above
$headers['To'] = $to;
$headers['Subject'] = $subject;
$mail = $smtp->send($theRecipient, $headers, $body);
// tried this, no help
$mail = $smtp->send($to, $headers, $body);
I need to get the Sender's email message to the Recipient's Inbox but the "From:" part of the email's title must not say "Sam Hambone (IamTheSender#gmail.com)".
What's missing here?
The best example of a website that probably everyone is familiar with is -- I have noticed that sites like Craigslist are always able to get emails routed to me when I place an ad to sell something (clothes, furniture, etc.)
There are other examples where a website 'relays' one of their user's email to my inbox successfully. That is what I was after, as that is what our site needs to do -- when a user needs to contact another user they send an email through our site (since that's how they came to be aware of the other user) and we need to relay their email to our other user.
No one (yet?) seems to have concrete experience on how to do this, so I'll close out this question in just a bit.
As you may or may not know, there is a war on spam *. This is because spammers are so prolific that they're using a significant amount of resources on servers like processing power (for filtering spam). They also threaten to ruin the usefulness of things like e-mail if we do not stop them. Therefore, because they're a major practical concern, there are all sorts of very sensitive spam filters across the internet that will put you in junk mail for reasons ranging like sending to too many messages that bounce, sending to a particularly unlucky inactive e-mail address (called a spam trap), etc. It is conceivable that the anti-spam software that is running is using this particular e-mail from format as one of it's heuristics to detect spam. It might be argued that using this as a heuristic is irrational or overly-sensitive, but as I've mentioned, the war on spam has resulted in some spam filtering mechanisms that are quite sensitive. If you want to do a test, perhaps try white listing the from e-mail address or turning off the spam filter(s) (in addition to server-side filters, e-mail clients and virus scanners may include some filtering abilities) and see if the spam filter is the culprit.
Update: Now that I am aware of the purpose of this e-mail software (to relay a message sent from the site from one user to another user, while presumably protecting their privacy) I can provide a better suggestion:
The notifications that I receive from websites to tell me that a user has messaged me simply contain the name of the website in the from line rather than a person's name. Example:
Website Name (no-reply#websitename.com)
(Note - it could be important to some spam filters that the website name in the from line matches the domain name exactly.)
If that doesn't seem to make it through the spam filter, I would try the following ideas:
Check out other "from" lines from other websites to see how they're doing it and try out any patterns you find.
Consider signing up with an e-mail reputation service to see whether they can help you.
Test to see whether this quirk is a big issue or a small one by determining which specific piece of spam software is flagging these, and then finding out how many users they have. You could also try sending these e-mails to a variety of other e-mail services to see whether they junk them. It may be that you have some old or unpopular spam filter here that's behaving in a way which actually is not indicative of what will happen to most of your e-mails.
Citation: "Spam Wars" by MIT Technology Review

Setting up Mail (PHP) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Send email using GMail SMTP server from PHP page
I'm pretty new to mail in PHP, and I am wanting to set up mail().
The problem is, after a few hours of trying to get it working, I simply can not!
I am wanting this to happen:
I want to send emails to the users on my website via my gmail address.
I am not sure WHERE i configure SMTP for gmail. Do i edit the settings in php.ini (ssl:smtp.gmail.com; 465)?
Is there a way to send emails using the PHP mail() function without the need to use something like pear? I am just wanting to use the mail() function.
If that is not possible, is there a way I can send emails to my users via the localhost setup?
I am pretty confused after looking around for answers during the past few hours.
Any help would be greatly appreciated!
The easiest way I've found to get PHP to send mail using SMTP is via the Mail Pear package.
This way you don't have to involve and obese third party libraries like PHPMailer.
Here's an example:
<?php
require_once "Mail.php";
$headers = array(
'From' => "Sandra Sender <sender#example.com>",
'To' => $to="Ramona Recipient <recipient#example.com>",
'Subject' => "Hi!"
);
$smtp = Mail::factory('smtp', array(
'host' => "ssl://smtp.gmail.com",
'port' => 465,
'auth' => true,
'username' => "smtp_username",
'password' => "smtp_password"
));
$body = "Hi,\n\nHow are you?";
$mail = $smtp->send($to, $headers, $body);
if (PEAR::isError($mail)) {
echo $mail->getMessage();
}
else {
echo "mail sent successfully";
}

imap headers of a quoted mail

I'm sending an email with some xheader.
When the recipient of the email replays to that email, i want to parse it, and get the content of that xheader from the mail i get by replay.
unfortunately, when i'm parsing the email i get back, i don't see my xheader.
(I printed the whole email, and the xheader is not there)
How can i do that in PHP with Zend Framework (i'm using Zend_Mail_Storage_Imap)?
Code:
$mail = new Zend_Mail_Storage_Imap(array(
'host' => 'pop.gmail.com',
'user' => 'a#gmail.com',
'password' => 'a',
'ssl' => 'SSL'
));
$count = $mail->countMessages();
$message = $mail->getMessage($count);
print_r($message);
//go through the message
foreach(new RecursiveIteratorIterator($message) as $part){
echo '*****************<br/>';
print_r($part);
echo '<br/>*****************<br/>';
//match parts content type to text/html - the one that maches is the message HTML body
if (preg_match('/.*text\/html.*/', $part->contentType)){
$body = $part->getContent();
}
$headers = $part->getHeaders();
if (isset($headers['X-aHeader'])){
echo $headers['X-aHeader'];
}
Thanks,
Boris.
Pekka gets points for the correct response here - X-headers in an original message will not necessarily be retained for any replies to that message. But, you're using Gmail, so you have another potential option.
Gmail allows plus addressing, so username#gmail.com will also receive mail for username+extra#gmail.com. If your X-aHeader content is alphanumeric, you can append it to your email address (e.g. a+headerdata#gmail.com). If your header content isn't alphanumeric, I'd recommend caching what you would put in the header locally on your system, and provide a uniqid as the email plus-address. When you receive a reply, you can use that uniqid to look up the data you cached locally.
This is a common technique for uniquely identifying recipients who reply to emails, or who perhaps bounce messages.

Best way to send mass email to my subscribers ( BCC or PEAR mail queue ? )

I need to send email to my 5000 subscribers.
What is the best way to do this ?
1) By using BCC ?:
$from_addr = 'myemail#example.com';
$mailing_list = 'sub1#example.com', 'sub2#example.com', 'sub3#example.com0;
$message_subject = 'this is a test';
`$headers = array ("From" => $from_addr,
"Bcc" => $mailing_list,
"Subject" => $message_subject);
$smtp = Mail::factory("smtp", array ('host' => "smtp.example.com",
'auth' => true,
'username' => "xxx",
'password' => "xxx"));
$mail = $smtp->send($email, $headers, $message_body);`
.
2) by using PEAR mail queue ?
I haven't used PEAR mail_queue yet, but using a queue is definitively the way to go!
BCC shouldn't be used because your mails would easily get flagged as Spam by big email providers like gmail/hotmail.
Also having thousands of addresses in an email header seems to be crazy. There may even be a limit. Also some mail servers could refuse your mail because of the over-sized header. On top of that the mail server that is supposed to send your email wouldn't be to happy about it.
Using built-in mail function is not the best way in the first place for that. I would suggest you to go for SwiftMailer which has HTML support, support for different mime types and SMTP authentication which is less likely to mark your mail as spam.
Also, you can check out this pear package:
http://pear.php.net/package/Mail_Queue

PHP Attaching an image to an email

Is there a way to attach an image to an html formatted email message created in PHP?
We need to ensure that a corporate logo is on emails sent to clients who may not have access to the internet whilst reading their email (They will obviously have it to download the files).
Try the PEAR Mail_Mime package, which can embed images for you.
You need to use the addHTMLImage() method and pass a content id (cid), which is a unique string of text you will also use in your img's src attribute as a cid: URL. For example:
include('Mail.php');
include "Mail/mime.php";
$crlf = "\r\n";
$hdrs = array(
'From' => 'foo#bar.org',
'Subject' => 'Mail_mime test message'
);
$mime = new Mail_mime($crlf);
//attach our image with a unique content id
$cid="mycidstring";
$mime->addHTMLImage("/path/to/myimage.gif", "image/gif", "", true, $cid);
//now we can use the content id in our message
$html = '<html><body><img src="cid:'.$cid.'"></body></html>';
$text = 'Plain text version of email';
$mime->setTXTBody($text);
$mime->setHTMLBody($html);
$body = $mime->get();
$hdrs = $mime->headers($hdrs);
$mail =& Mail::factory('mail');
$mail->send('person#somewhere.org', $hdrs, $body);
It's probably easiest to use some library that can deal with email attachments. For example, PEAR's Mail_Mime.
PEAR's Mail_Mime package is what you're after here.
Once you've set your message up, adding an attachment is as simple as:
$mime = new Mail_mime("\n");
$mime->setTXTBody($msg_text);
$mime->setHTMLbody($msg_html);
// Add gif as attachment to mail
$mime->addAttachment("/path/to/image/smile.gif", "image/gif");
$body = $mime->get();
$headers = $mime->headers($headers);
$mail->send("joe#bloggs.com", $headers, $body);
If you're looking for your logo to display in a particular place in the email - rather than solely as an attachment - you can do the following:
// In your message html:
<img src='logo.gif' alt='Our logo' />
// PHP:
$mime->addHTMLImage('/path/to/image/logo.gif');
This approach can have mixed results depending on your user's mail client, so before sending it out try testing your format on dummy gmail, yahoo and hotmail accounts.
Are you rolling your own, or using a
prefab class? I recommend PHP
Mailer[0] myself, and there's also
PEAR::Mail_Mime[1] among others that
Google would be happy to help you
find. I've been using PHP Mailer to
send messages with embedded images[2]
for years without a hitch, though bear
in mind that each image increases the
email's bandwidth weight hugely, so
generally it should not be used for
anything in bulk. And to echo Bill,
do make use of the text-only alternative too.
[0] http://phpmailer.sourceforge.net/
[1] http://pear.php.net/manual/en/package.mail.mail-mime.php
[2] http://phpmailer.sourceforge.net/docs/PHPMailer/PHPMailer.html#AddEmbeddedImage
taken from http://lists.evolt.org/archive/Week-of-Mon-20060612/183029.html
There are more than enough answers here that should help fix your specific problem, but I just thought it might be worth pointing out that you may well have a larger problem that you hadn't considered.
Specifically - writing emailers to be sent via PHP is filled with potential gotchas and should only be done if you have a really good idea of what can go wrong.
If you're planning on sending emails fairly intensively I would strongly suggest doing it through either a dedicated email marketing client or implementing one of the many email marketing API's out there that will send it for you. (mailchimp is apparently a decent one).
Try out swiftmailer here is a good example how to use embedded image http://swiftmailer.org/wikidocs/v3/embedding_images?s[]=embed

Categories