Hi Franklin,
On two separate systems, the following PHP test script works:
<?phperror_reporting(E_ALL);$sock=fsockopen('tls://email-smtp.us-east-1.amazonaws.com',465);if($sock) echo "Socket established\n"; else exit("Socket could not be established\n");echo fgets($sock,1024);echo "> EHLO localhost\n";fputs($sock,"EHLO localhost\r\n");$line='';while(substr($line,3,1)!==' '){ $line=fgets($sock,1024); echo $line;}
The result when run from browser or commandline is e.g.:
Socket established
220 email-smtp.amazonaws.com ESMTP SimpleEmailService-908880847 2G85c3kZxdN3aiX48I3
> EHLO localhost
250-email-smtp.amazonaws.com
250-8BITMIME
250-SIZE 10485760
250-AUTH PLAIN LOGIN
250 Ok
For me, everything seems to be working as expected. The SMTP conversation should be able to continue as normal. LMP does it the same way.
If this test doesn't return similar results for you you will need to speak with your host as they may have limited or restricted such PHP socket connections or be experiencing a technical issue.
Regards
Hi Brett,
I'm hoping that Dean (the author of LMP), can soon provide us with a method to setup/configure Amazon SES with Amazon SNS to track complaints/bounces of messages
Try this:
<?php// LMP Amazon SES SNS Complaint & Bounce Processing// based on https://github.com/npflood/AWS-SNS-HTTP-PHP-ENDPOINT/blob/master/receiver.php//// Name this file ses_bounce.php or similar, put it in your LMP folder, and (after configuring below) set its URL as an SNS HTTP endpoint (also configure SES to publish to the SNS topic)// Change $allowedTopic below to your full SNS topic// Change $sourceDomain below to suit your region// see bottom for LMP////////// CONFIGURATION////////For Debugging.$logToFile = false;//Should you need to check that your messages are coming from the correct topicArn$restrictByTopic = true;$allowedTopic = "arn:aws:sns:us-west-2:100885381234:SES_Complaints_and_Bounces";//For security you can (should) validate the certificate, this does add an additional time demand on the system.//NOTE: This also checks the origin of the certificate to ensure messages are signed by the AWS SNS SERVICE.//Since the allowed topicArn is part of the validation data, this ensures that your request originated from//the service, not somewhere else, and is from the topic you think it is, not something spoofed.$verifyCertificate = true;$sourceDomain = "sns.us-west-2.amazonaws.com"; ////////// OPERATION//////$signatureValid = false;$safeToProcess = true; //Are Security Criteria Set Above Met? Changed programmatically to false on any security failure.if($logToFile){ ////LOG TO FILE: $dateString = date("Ymdhis"); $dateString = $dateString."_r.txt"; $myFile = $dateString; $fh = fopen($myFile, 'w') or die("Log File Cannot Be Opened.");}//Get the raw post data from the request. This is the best-practice method as it does not rely on special php.ini directives//like $HTTP_RAW_POST_DATA. Amazon SNS sends a JSON object as part of the raw post body.$json = json_decode(file_get_contents("php://input"));//Check for Restrict By Topicif($restrictByTopic){ if($allowedTopic != $json->TopicArn){ $safeToProcess = false; if($logToFile){ fwrite($fh, "ERROR: Allowed Topic ARN: ".$allowedTopic." DOES NOT MATCH Calling Topic ARN: ". $json->TopicArn . "\n"); } }}//Check for Verify Certificateif($verifyCertificate){ //Check For Certificate Source $domain = getDomainFromUrl($json->SigningCertURL); if($domain != $sourceDomain){ $safeToProcess = false; if($logToFile){ fwrite($fh, "Key domain: " . $domain . " is not equal to allowed source domain:" .$sourceDomain. "\n"); } } //Build Up The String That Was Originally Encoded With The AWS Key So You Can Validate It Against Its Signature. if($json->Type == "SubscriptionConfirmation"){ $validationString = ""; $validationString .= "Message\n"; $validationString .= $json->Message . "\n"; $validationString .= "MessageId\n"; $validationString .= $json->MessageId . "\n"; $validationString .= "SubscribeURL\n"; $validationString .= $json->SubscribeURL . "\n"; $validationString .= "Timestamp\n"; $validationString .= $json->Timestamp . "\n"; $validationString .= "Token\n"; $validationString .= $json->Token . "\n"; $validationString .= "TopicArn\n"; $validationString .= $json->TopicArn . "\n"; $validationString .= "Type\n"; $validationString .= $json->Type . "\n"; }else{ $validationString = ""; $validationString .= "Message\n"; $validationString .= $json->Message . "\n"; $validationString .= "MessageId\n"; $validationString .= $json->MessageId . "\n"; if($json->Subject != ""){ $validationString .= "Subject\n"; $validationString .= $json->Subject . "\n"; } $validationString .= "Timestamp\n"; $validationString .= $json->Timestamp . "\n"; $validationString .= "TopicArn\n"; $validationString .= $json->TopicArn . "\n"; $validationString .= "Type\n"; $validationString .= $json->Type . "\n"; } if($logToFile){ fwrite($fh, "Data Validation String:"); fwrite($fh, $validationString); } $signatureValid = validateCertificate($json->SigningCertURL, $json->Signature, $validationString); if(!$signatureValid){ $safeToProcess = false; if($logToFile){ fwrite($fh, "Data and Signature Do No Match Certificate or Certificate Error.\n"); } }else{ if($logToFile){ fwrite($fh, "Data Validated Against Certificate.\n"); } }}if($safeToProcess){ //Handle A Subscription Request Programmatically if($json->Type == "SubscriptionConfirmation"){ //RESPOND TO SUBSCRIPTION NOTIFICATION BY CALLING THE URL if($logToFile){ fwrite($fh, $json->SubscribeURL); } $curl_handle=curl_init(); curl_setopt($curl_handle,CURLOPT_URL,$json->SubscribeURL); curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); curl_exec($curl_handle); curl_close($curl_handle); } //Handle a Notification Programmatically if($json->Type == "Notification"){ //Do what you want with the data here. //fwrite($fh, $json->Subject); //fwrite($fh, $json->Message); }}//Clean Up For Debugging.if($logToFile){ ob_start(); print_r( $json ); $output = ob_get_clean(); fwrite($fh, $output); ////WRITE LOG fclose($fh);}//A Function that takes the key file, signature, and signed data and tells us if it all matches.function validateCertificate($keyFileURL, $signatureString, $data){ $signature = base64_decode($signatureString); // fetch certificate from file and ready it $fp = fopen($keyFileURL, "r"); $cert = fread($fp, 8192); fclose($fp); $pubkeyid = openssl_get_publickey($cert); $ok = openssl_verify($data, $signature, $pubkeyid, OPENSSL_ALGO_SHA1); if ($ok == 1) { return true; } elseif ($ok == 0) { return false; } else { return false; } }//A Function that takes a URL String and returns the domain portion onlyfunction getDomainFromUrl($urlString){ $domain = ""; $urlArray = parse_url($urlString); if($urlArray == false){ $domain = "ERROR"; }else{ $domain = $urlArray['host']; } return $domain;}// LMP - Process Bounce or Complaint// per http://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-examples.htmlinclude('./config.php');include('./admin.php');if($json->notificationType=='Bounce'){ if($json->bounce->bounceType=='Permanent'){ foreach($json->bounce->bouncedRecipients as $r){ // set user to bounced mysql_query("UPDATE $utable SET cnf = '3' WHERE email LIKE '".addslashes($r->emailAddress)."';") or die(mysql_error()); } }} elseif($json->notificationType=='Complaint'){ foreach($json->complaint->complainedRecipients as $r){ // set user to removed mysql_query("UPDATE $utable SET cnf = '2' WHERE email LIKE '".addslashes($r->emailAddress)."';") or die(mysql_error()); }}?>
I'll have to consider the queue size issue further.
Regards
i am revisiting this topic-- as I am trying again after some years to get SES to work with my listmailpro instalation
i switched hosts
and tested the code that was provided earlier
<?phperror_reporting(E_ALL);$sock=fsockopen('tls://email-smtp.us-east-1.amazonaws.com',465);if($sock) echo "Socket established\n"; else exit("Socket could not be established\n");echo fgets($sock,1024);echo "> EHLO localhost\n";fputs($sock,"EHLO localhost\r\n");$line='';while(substr($line,3,1)!==' '){ $line=fgets($sock,1024); echo $line;}
this is working and not giving me any error messages..
================================
I set up my domain and emails in Amazon SES
and got my smtp credentials
--- i tested these credentials in thunderbird--
and i have no problem signing into the amazon ses server and sending email
putting the smtp credentials into listmailpro configuration screen:
testing the mail connection gives:
Testing mail servers..
[Bounce Handling]
Is enabled? No (you should probably configure it)
[SMTP Server]
Is enabled? Yes
Connecting to SMTP server.. Connected!
Could not say EHLO.
The SMTP server is not configured correctly. Check your settings.
============================
trying to send a mass email
(to a test list and only one test subscriber)
I get a failed error message that smtp was not set up correctly
log file shows:
> EHLO localhost
=================================
I get the same error message when testing mail settings and sending a test email to a list
when AUTH? is checked and when it is not checked...
Is there something simple that I am missing?
Franklin