1

I recently set up an alert system whereby when certain APIs are called, it alerts me (or others) via PHP's mail() function.

On email's it works totally fine. The function returns true and it is received in the mailbox where it is sent to.

For some reason when sending to an SMS gateway (i.e. XXXXXXXXXX@messaging.sprint.com) the function sends it (it does return true) however it never gets received on the other end.

If I take that same exact email address (that goes to an sms gateway) and send it via an email client (such as zimbra or whatever), it goes through fine and it is received by the person.

I am the web designer and not really the email / IT person. I am assuming it has something to do with headers or something along this line, however I am not versed on this technical subject.

I spoke to my IT guy and he said that it is erroring and looks like there is no proper "From" address in the headers. Instead of coming from a valid email address, the email errors and looks like it is coming from "www.data@[server-name]" instead of what I am sending via the header which is a valid email address.

here is a snippet of my code:

<?php

$carriers = array("@messaging.sprintpcs.com");

//get to email
if (isset($_POST['to'])) {
$to = $_POST['to'];
}

// get from email
if (isset($_POST['from'])) {
$from = $_POST['from'];
$fromHeader = "From: ".$from."\r\n Sender: ".$from."\r\n";
}

// get subject
if (isset($_POST['subject'])) {
$subject = $_POST['subject'];
}

// get message
if (isset($_POST['message'])) {
$message = $_POST['message'];
}

// get cc
if (isset($_POST['cc'])) {
    if ($_POST['cc']!="") {
    $ccHeader = "CC: ".$_POST['cc']."\r\n";
    }
    else {
    $ccHeader="";
    }
}
else {
$ccHeader="";
}

// get bcc
if (isset($_POST['bcc'])) {
    if ($_POST['bcc']!="") {
    $bccHeader = "Bcc: ".$_POST['bcc']."\r\n";
    }
    else {
    $bccHeader="";
    }
}
else {
$bccHeader="";
}

// get reply to
if (isset($_POST['replyTo'])) {
    if ($_POST['replyTo']!="") {
    $replyToHeader = "Reply-To: ".$_POST['replyTo']."\r\n";
    }
    else {
    $replyToHeader="";
    }
}
else {
$replyToHeader="";
}

$additionalHeaders = "Content-Type: text/plain; charset=\"utf-8\" Content-Transfer-Encoding: 8bit \r\n";

$headers = $fromHeader.$ccHeader.$bccHeader.$additionalHeaders;

foreach ($carriers as $carrier) {

    $number = get_numeric_only($to).$carrier;

    if (mail($to,$subject,$message,$headers)) {
        $response = array("response" => "SUCCESS");
    }
    else {
        $response = array("response" => "ERROR");
    }

}

echo json_encode($response);

?>

edit:

I changed the mail() function by adding a 4th parameter so it looks like this as apparently this would help:

mail($to,$subject,$message,$headers,'-f[myaddress]@[mydomain].com')

Then the sms-email bounced BACK to the "from" email address as stated in the headers with the following:

The original message was received at Wed, 28 Jan 2015 19:10:32 -0500
from localhost [127.0.0.1]

   ----- The following addresses had permanent fatal errors -----
<xxxxxxxxxx@messaging.sprintpcs.com>
    (reason: 550 Host unknown)

   ----- Transcript of session follows -----
550 5.1.2 <xxxxxxxxxx@messaging.sprintpcs.com>... Host unknown (Name     server: messaging.sprintpcs.com: host not found)

Does this jog anybody's head? .....

Walker Farrow
  • 3,579
  • 7
  • 29
  • 51
  • 2
    Going off of what your IT guy said, are you setting the "From" header to a valid address? – Jon Egeland Jan 28 '15 at 14:58
  • 2
    To limit spamming, the From email address must come from the server. For example, if my server's hostname is "ilovespam.com" and the From email address I use is "potus@whitehouse.gov", the receiving server (Sprint) will kick it back. I will get a "true" stating that the email was sent, but the email will not be received. It is not possible for PHP to know if the email was received because once it is sent, it is on another server. – kainaw Jan 28 '15 at 15:03
  • Ok, this makes sense what you are saying (kainaw), but I am still feeding into the header the from address - just as I would if sending a normal email. I send emails on this same API and it delivers fine. Is there some reason it would change just because I am sending it to an SMS gateway? I am feeding the SAME from header value as I am when sending a normal email... – Walker Farrow Jan 28 '15 at 22:07
  • You'll probably save yourself a lot of mail server hassles if you setup an actual email address to send your SMSes from and use SMTP in PHP to send the email using a valid email address. I'd recommend finding a good package on Packagist (like https://packagist.org/packages/swiftmailer/swiftmailer) – Tom Feb 01 '15 at 22:30
  • Going a little off topic here but it's extremely important so I'll chime in anyway. Will your production code do any more validation on the input than this code? If not then you seriously need to put some in because otherwise you're opening yourself to all manner of attacks! – Ryan Lund Feb 02 '15 at 21:23
  • Yes, I have stripped it down before posting it. Off-topic, but certainly valid point. – Walker Farrow Feb 02 '15 at 21:37
  • Haha good to know - you had me worried for a moment there ;) – Ryan Lund Feb 02 '15 at 23:27

6 Answers6

2

OK firstly you're allowing a random stranger (who submits the POST request) to set the FROM address of the email message by accessing $_POST['from'] and using that as the FROM address. That's not going to work if (as others have suggested) you're setting a FROM address that is not a valid sender address according to your mail server -- and according to whatever upstream mail server you're using. So, for example, in my own network I can send an email "From: me@mydomain.com" but if I send something that is addressed "From: you@fakedomain.com" then it will probably bounce or be thrown out. So you probably need to hard code that From address to whatever your IT guys say, not use the $_POST variable.

The fact that your email is actually going out as "From: www.data@servername" probably means a couple of things:

  • Your PHP is configured so that the mail() function calls the standard sendmail command installed on most Unix/Linux systems.
  • Your Apache server, that is running the PHP processes, is running as the "www.data" user on that system.
  • The "www-data" user on that system is not authorized to set an alternative FROM address, and so sendmail is forcing the FROM address to be www.data@servername, regardless of what you tell it.

Your system admin needs to tell you what address to hard code as the FROM address on that system. In addition, he or she needs to configure the mail system to allow www.data to set its own FROM address. Assuming that you are using actual real sendmail (and not something else configured to work like sendmail, such as postfix), then that would be done by adding a line "www.data" to the file /etc/mail/trusted-users or whatever trust file is set up on that system. The clue to that is to find the sendmail.cf file in use on the system and look for a line beginning with "Ft", e.g.

Ft/etc/mail/trusted-users

More information can be found in the sendmail docs, e.g. on a Red Hat / CentOS system with the sendmail-cf package installed there will be a /usr/share/sendmail-cf/README file on that system with useful information in it about trusted-users.

delatbabel
  • 3,601
  • 24
  • 29
  • Thanks - all these answers have been helpful and this is the most helpful that helped me solve it - soo.... the bounty goes to Delatbabel! Thanks for all your posts guys. – Walker Farrow Feb 06 '15 at 03:33
2

First off, I would highly suggest you read up on the limitations on email-to-SMS. It's an older thread but I have no reason to believe that the limits are any better now. Remember, SMS is not free to some users so carriers have some incentive to limit what you can do.

Second, the relevant data for your email would be in your mail server logs. Too many people think that because mail() returned true, that the email was sent. All mail() can do is tell you if sendmail (or whatever MTA you use) responded with. If you check out the mail log (typically in /var/log/maillog for most Linux distros) and look for the address you sent to, you will see if sendmail was actually successful in sending the email or if the recipient server rejected it. I'm willing to bet, based on my first point, that you got filtered in some way. If you don't have a properly formatted from address, your server will use username@server-hostname which tends to look like apache@23247244efg.myhostingcomapny.com (major YMMV, as some virtal servers don't even have a FQDN)

Third, you should consider a SMS service. Amazon, for instance, has its SNS service, where you pay-per-usage (there are other services with monthly fees, etc). The advantage here is clear, because you're using something designed to push notices via SMS, instead of a weak (and likely deprecated) method of achieving the same thing. And, this way, you don't have to deal with any headaches of making sure your email is formatted so the carriers will accept it.

Community
  • 1
  • 1
Machavity
  • 30,841
  • 27
  • 92
  • 100
1

If you know the provider of the phone number you can use the email to sms service by most companies.

Ex:

Rogers Wireless: [10-digit phone number]@pcs.rogers.com

Fido: [10-digit phone number]@fido.ca

Telus: [10-digit phone number]@msg.telus.com

Bell Mobility: [10-digit phone number]@txt.bell.ca

Kudo Mobile: [10-digit phone number]@msg.koodomobile.com

MTS: [10-digit phone number]@text.mtsmobility.com

President’s Choice: [10-digit phone number]@txt.bell.ca

Sasktel: [10-digit phone number]@sms.sasktel.com

Solo: [10-digit phone number]@txt.bell.ca

Virgin: [10-digit phone number]@vmobile.ca

Cheers

geggleto
  • 2,605
  • 1
  • 15
  • 18
0

There are 2 solutions (that I know):

A SMS Gateway Provider or Using a GSM modem.

For the first one, it's the simplest one, you have to use an API of your provider. It can also be through SMTP. The process depends on the provider. Often, you have to provide some extra headers.

Using a GSM modem (i've tried it), you have to launch some commands to your modem, it's not so difficult but, the modem is about 350$

Mirza Selimovic
  • 1,669
  • 15
  • 18
  • Well, I have two problems on this. One is that I am in a closed network (not really open to internet). So an on-line API call is a little difficult. But if it works on SMTP, what does that mean? Like there is a service I can send an email to with certain headers who would then forward it as SMS? Is there anything I can read up on this? – Walker Farrow Feb 03 '15 at 20:10
0

First, check to see if your server ip is on any blacklists. If so, try to get removed from them. Second, Use a valid from address that indicates its coming from your server, don't spoof. I have had no problem sending email from my server when I did that.

(please note the end user may be charged for these messages, and the recipient may need to enable this feature)

anonman
  • 98
  • 1
  • 8
0

The problem is most likely due to the fact that sprintpcs DNS records are broken. This may be deliberate to prevent people abusing their service. You may be able to get around this by using an SMTP client connecting directly to the nonauthoritative address.

symcbean
  • 47,736
  • 6
  • 59
  • 94