Modifying & Relaying Mail - php

Is there any way to simply relay mails received by a PHP script? Instead of being received normally into a mailbox, I have routed all incoming mails to a PHP script that would parse and log them (from, subject, message text) into a text file.
This is the truncated version of the script:.
<?php
$feed = fopen ("php://stdin", 'r');
$email = '';
while (!feof($feed))
{
$email .= fread($feed, 1024);
}
fclose($feed);
$to = explode...
$from = explode..
$subject = explode...
$message = utf8_encode...
$log = fopen("/home/.../log.txt", "a+");
fwrite($log,...);
fclose($log);
?>
Would it be possible to relay the entire message, as is, to another recipient, but not as a forward?
TIA.

Apparently, the email is received with a whole bunch of additional headers, from the original sender. So, it must be parsed, and only the required headers extracted and used. The relevant header entries could also be modified to change the sender & recipient information, as well as the subject. Once all that is done, the PHP mail() function could be used to re-send the email.
Simple, and it works. The only drawback is that GMail keeps reporting that the sender cannot be confirmed as the actual sender (or spammer).

Related

E-mail piping with e-mail forwarder does not work

I have a simple email pipe script. But I need a copy of the incoming e-mail going to another e-mail address. Unfortunately I do not receive the e-mail as I wanted.
The code;
#!/usr/bin/php -q
<?php
$email_msg = ''; // the content of the email that is being piped
$email_addr = 'sales#flensmuts.nl'; // where the email will be sent
$subject = 'Piped:'; // the subject of the email being sent
// open a handle to the email
$fh = fopen("php://stdin", "r");
// read through the email until the end
while (!feof($fh)){
$email_msg .= fread($fh, 1024);
}
fclose($fh);
// send a copy of the email to your account
mail($email_addr, $subject, "Piped Email: ".$email_msg);
?>
Your mail server logs will probably say something about this. My guess is that it might be failing because your message is malformed because of the prefix you're adding. Try sending the message untouched, like this:
mail($email_addr, $subject, $email_msg);
Separately, for simple forwarding like this, you can probably set up your mail server to do this directly without having to go via a script.
There is no error checking in your script. There is no instrumentation in your script to see if it is even being run. You have not said why you believe that the script is being triggered. You have not said how mail() works on your test site.
Decompose the issues. Replace this script with one which dumps stein to a file to find out if there is an issue with the input integration.
Write and run a script which sends an email when using mail() when manually invoked. If you control the MTA then read your logs - even if these experiments are successful.
Then go back to your original script. Add some logging. Check the value returned by mail(). Check that the delivery path accepts forwarded mail with a broken envelope.

Can't embed variable in mail function php

I want to send email with different subjects. I have the following code that get mail subject and message from the database.
$sql = "SELECT mail_subject, mail_content FROM new_business WHERE business_name = '$biz_name'";
$query = mysqli_query($db, $sql);
while ($row = mysqli_fetch_array($query)) {
$subject = $row['mail_subject']; //Getting mail subject to send
$mail_content = $row['mail_content']; //Getting mail content
}
echo $subject; //checking if it gets subject and it surely does.
$to = 'utopian51#gmail.com';
mail($to, $subject, $mail_content);//Mail is not sent
If subject pulls data from database mail is not sent. I have checked several times including spam and also checked if subject gets any data from database before embedding it in mail function. It seems it gets the right data but the mail is not sent.
But when i hardcode the subject like this: $subject = 'this is a test subject'; , the mail is sent successfully. Why mail function does not let me embed variable that gets subject from database? I need to send the mails with different subject from database. Whats the solution?
There's many things which are confusing about the code you've written. You never check for error conditions in the mysqli_ calls nor the mail() call. You run a query which will discard all but the last row (if any). However the way to diagnose issues with mail() is not to watch your inbox. In more than 99% of cases the problem is with the interface between PHP and the MTA or with the MTA configuration itself.
You have provided no details of either.
I would recommend you use simply:
mail('utopian51#gmail.com', 'test', date('r'));
and start debugging your MTA.
Independently you can work on your bulk emailing script, simply writing to a file instead of calling mail() until both parts are working.

500 error after PHP mail()

UPDATE
I was able to get the hosting info from my client and I contacted support, apparently there's an issue with the hosts mail function at the moment and they are working on a resolution. Will wait to see if that's the cause of this problem and will report back.
END UPDATE
I am trying to set up a simple contact form that will send an email. I have the form action set to the below PHP file.
The email gets sent, but the user experience ends with a 500 error instead of sending the user to the confirmation page.
If I comment out the mail() part, then the form redirects the user to the confirmation page successfully, but of course no email gets sent.
The website is hosted on GoDaddy, and I don't have access to the hosting account, though I can try to get it if I need it.
Here's the PHP code:
<?php
$name = $_POST['name'];
$address = $_POST['address'];
$city = $_POST['CITY'];
$state = $_POST['state'];
$zip = $_POST['zip'];
$email = $_POST['email'];
$howdidyouhear = $_POST['hear_about'];
$notifyshow = $_POST['notify_shows'];
$notifyonline = $_POST['notify_online'];
$interest_jewelry = $_POST['Interest_jewelry'];
$interest_prints = $_POST['interest_prints'];
$interest_folkart = $_POST['interest_folkart'];
$interest_indian = $_POST['interest_indian'];
$interest_closeouts = $_POST['interest_closeouts'];
$interest_other = $_POST['interest_other'];
$interest_other_text = $_POST['interest_other_text'];
$spamvalid = $_POST['validate'];
$honeypot = $_POST['website'];
//Spammer Handling
if ($honeypot!=null){echo 'You have been flagged as a spammer, please go away!'; exit;}
if ($spamvalid != '357'){
echo "
<script>
function goBack() {
window.history.back()
}
</script>
You didn't enter the correct number at the bottom of the form. Please try again.<br><button onclick='goBack()'>Go Back</button>";
exit;
}
//START EMAIL
//Body
$mailbody="Name: {$name}\n\nAddress: {$address}\n\nCity: {$city}\n\nState: {$state}\n\nZip: {$zip}\n\nEmail: {$email}\n\nHow did you hear about us?: {$howdidyouhear}\n\nWould you like to be notified when we will be doing a show in your area?: {$notifyshow}\n\nWould you like to receive email notifications of special sales and online events?: {$notifyonline}\n\nWhat brought you to mishuganah.com?: {$interest_jewelry} {$interest_prints} {$interest_folkart} {$interest_indian} {$interest_closeouts} {$interest_other}: {$interest_other_text}\n\n";
//Send Email
mail('matt.rodela#gmail.com','New submission from Mishuganah.com', $mailbody, "From:{$email}\r\n" );
header("Location: http://".$_SERVER["HTTP_HOST"]."/mailing_list/confirmation_page.htm");
?>
I am a relative novice with PHP, so please explain your solutions fully. Thanks!
Use phpMailer instead of php mail() function below you will find reasons not to use built in php mail function
In some cases, mails send via PHP mail() did not receive the recipients although it was send by WB without any error message. The most common reasons for that issue are listed below.
wrong format of mail header or content (e.g. differences in line break between Windows/Unix)
sendmail not installed or configured on your server (php.ini)
the mail provider of the recipeint does not allow mails send by PHP mail(); common spam protection
Errors in the format of header or content can cause that mails are treated as SPAM. In the best case, such mails are transfered to the spam folder of your recipient inbox or send back to the sender. In the worst case, such mails are deleted without any comment. If sendmail is not installed or not configured, no mails can be send at all.
It is common practice by free mail provider such as GMX, to reject mails send via the PHP function mail(). Very often such mails are deleted without any information of the recipient.
So it turns out it was an issue on GoDaddy's end and it has been resolved. The form is working now. Apparently there was nothing wrong with the code.
Thanks for the suggestions folks, I learned some stuff (going to sanatize and filter my inputs now).

Proper prevention of mail injection in PHP

Could you advise me how do I go about preventing email injection in PHP mail() without losing original message data? E.g. if I need to allow user to use \r\n, To, CC etc, so I do not want to completely strip them away from the message - I still want them delivered, but without adding any additional headers or somehow allowing mail injection to happen.
Most of the advices on internet suggest stripping that data away completely - but I do not want to do that.
I am sending plain text (non HTML) messages through PHP mail() function.
What would you advise?
To filter valid emails for use in the recipient email field, take a look at filter_var():
$email = filter_var($_POST['recipient_email'], FILTER_VALIDATE_EMAIL);
if ($email === FALSE) {
echo 'Invalid email';
exit(1);
}
This will make sure your users only supply singular, valid emails, which you can then pass to the mail() function. As far as I know, there's no way to inject headers through the message body using the PHP mail() function, so that data shouldn't need any special processing.
Update:
According to the documentation for mail(), when it's talking directly to an SMTP server, you will need to prevent full stops in the message body:
$body = str_replace("\n.", "\n..", $body);
Update #2:
Apparently, it's also possible to inject via the subject, as well, but since there is no FILTER_VALIDATE_EMAIL_SUBJECT, you'll need to do the filtering yourself:
$subject = str_ireplace(array("\r", "\n", '%0A', '%0D'), '', $_POST['subject']);
Suppose you you want to put the email address of the visitor in the optional header field like so:
$headers = "From: $visitorEmailAddress";
However, if
$visitorEmailAddress
contains
"address#email.com\n\nBCC:spam#v1agra.com"
you've made yourself a spam host, opening the door for mail injection.
This is a very simple example, but creative spammers and malicious hackers can sneak potentially damaging scripts in your email, since email is sent as a plaintext file. Even attachments are converted plaintext, and they can easily send attachements by adding a mimetype content line.
If your form validation for the FROM and/or TO fields is OK, you have to look at the form validation for the body of the email. I'd strip out the '-=' and '=-' characters, and prevent users from typing plain HTML by using strip_tags().
Try this for a review of various options:
http://www.codeproject.com/Articles/428076/PHP-Mail-Injection-Protection-and-E-Mail-Validatio
It covers several options and tries to explain the benefits and risks of each.
Use a designated mime email library, like Mail_Mime:
<?php
include 'Mail.php';
include 'Mail/mime.php' ;
$mime = new Mail_mime();
$mime->setTXTBody("Message goes here");
$hdrs = $mime->headers(array(
'From' => 'you#yourdomain.com',
'Subject' => 'Test mime message'
));
$body = $mime->get();
$mail = &Mail::factory('mail');
$mail->send('postmaster#localhost', $hdrs, $body);
?>

PHPmailer sends to junk email

I've just updated a contact form to use PHPMailer to stop emails being marked as junk, with no luck.
It's a fairly straight forward setup I'm using but its still going into peoples junk mail.
Here is my script, I was wondering if anyone could tell what was wrong?
include_once('../inc/phpmailer/class.phpmailer.php');
$mail = new PHPMailer();
$name = $_POST['name'];
$email = $_POST['email'];
$body = "Name: ".$name."\r\n";
$body .= "Email: ".$email."\r\n";
$body .= "Message: ".$_POST['message'];
$mail->From = "mailer#blah.com";
$mail->FromName = "Contact BLah";
$mail->Subject = "Contact From: Blah";
$mail->Body = $body;
$mail->AddAddress("john#blah.com", "john");
$mail->AddAddress("david#blah.com", "david");
if(!$mail->Send()) {
$errorMsg .= "Error sending message, please try again later.";
} else {
$errorMsg .= "Message Sent successfully.";
}
I thought that PHPmailer normally takes care of inserting proper headers?
Any thoughts?
EDIT: Added spam score
-Spam-Status: "score=0.0 tests=none version=3.1.7 cmae=v=1.0 c=1 a=8nJEP1OIZ-IA:10
a=soyWjZv28gkhNSke5wm04A==:17 a=fqdOs_Nl9wd82e3SDigA:9 a=l-lynuxnH-gfU2bevBoA:7
a=wPNLvfGTeEIA:10 a=nymK5Bb5l1cA:10 a=_6wjLm_vFSYA:10 xcat=Undefined/Undefined"
X-Spam-Level: *
EDIT 2: I just tried the script on a different server from the clients and it has the same result. Do I have to send through the SMTP setup for it not to be classed as spam?
Some reasons your mail can get marked spam:
You're sending spam
Your IP, or a block of IPs surrounding your IP has been marked as a spam source on one or more blackhole lists
The content of the email is triggering spam filters.
The recipient has added you to their blacklist
The recipient didn't add you to their whitelist
You're sending a mixed source mail ("From: xyz#example.com", but sending it from "someotherdomain.net")
SPF records for your server are misconfigured/not configured at all
Domain keys are misconfigured/not configured at all
etc...
PHPMailer is a tool. Consider it a hammer. The hammer may have bent the nail, but only because the wielder didn't aim right.
The only way you'll solve this problem is by examining the bounce messages (if any), and whatever showed up in the recipient's mailbox. If they receive the mail, but it goes into a spam folder, then get a copy of the mail and examine its headers. Most spam filters will put their spam score/reasoning in there.
Small hint:
add in a line like so
$mail->AddReplyTo( 'mailer#blah.com', 'Contact BLah' );
It should decrease your SPAM rating significantly.
I was having the same problem using PHPMailer, and here's what fixed the problem for me: set the Sender (this is different and distinct from the "From") to a valid email account for the domain you are sending the email from. This causes PHPMailer to properly set the "envelope-from" information so that the email passes SPF and Sender-ID validation. Without doing this, the "envelope-from" is a OS user id and server combination which will not be verifiable.
Example Code:
$mail = new PHPMailer;
$mail->From = 'from_email#domain.com';
$mail->Sender = 'sender_email#domain.com';
...
It is not necessarily PHPMailer's fault, there are several possible reasons for your server to be blacklisted. You can check here to see if this happened

Categories