Bad Mime with PHP Mail? - php

I've migrated a site from one server to another. On the old server the contact page works fine, on the new one it doesn't. I've contacted support and they sent me the log which doesn't reveal anything asides form an unrelated undeclared variable. I contact again and was able to find out that another error was being generated :
policy-violation_found_in_sent_message_"Contact_Form"
Policy:Bad_MIME:RC:1
Can anyone help please?
The bulk of the code is below, I can't see the problem, on one server it works fine, on another it doesn't.
Thanks for any help.
if(isset($_POST['name'])){ //may have to change to see if a field was set instead
$myEmail = 'me#me.com'; //Email address where queries get sent.
//errors already defined in init
$name = strip_tags(trim($_POST['name']));
$email = strip_tags(trim($_POST['email']));
$subject = "Contact Form";
$headers = "From: " .$email. "\r\n";
$headers .= "Reply-To: " .$email. "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
//body of message
$message1 = '<html><body>';
$message1 .= '<table rules="all" style="border-color: #666;" cellpadding="10">';
$message1 .= "<tr style='background: #eee;'><td><strong>Name:</strong> </td><td>" .$name. "</td></tr>";
$message1 .= "<tr><td><strong>Email:</strong> </td><td>" .$email. "</td></tr>";
$message1 .= "<tr><td><strong>Message:</strong> </td><td>" .$message. "</td></tr>";
$message1 .= "</table>";
$message1 .= "</body></html>";
if (mail($myEmail, $subject, $message1, $headers)) {
//Whoop!
} else {
echo 'There was a problem sending the email.';
}
}
I've removed fields and some validation etc but thats the bulk of it.

Policy:Bad_MIME:RC:1 is an error message of qmail_scanner set up by your hosting provider. It's not directly related to PHP.
From its source code:
if (!$quarantine_event && $illegal_mime && $headers{'mime-version'} && $BAD_MIME_CHECKS) {
$destring="problem";
$quarantine_description="Disallowed characters found in MIME headers" if (!$quarantine_description);
$quarantine_event="Policy:Bad_MIME";
$description .= "\n---perlscanner results ---\n$destring '$quarantine_description'\n found in message";
}
So basically it doesn't like some characters in your MIME headers.
My guess is that it doesn't like the \r character, since you seem to have those, and it does this check
if ($BAD_MIME_CHECKS && !$IGNORE_EOL_CHECK && /\r|\0/) {
$illegal_mime=1;
&debug("w_c: found CRL/NULL in header - invalid if this is a MIME message");
&minidebug("w_c: found CRL/NULL in header - invalid if this is a MIME message");
}
so using just \n instead of \r\n might resolve the problem.
If it doesn't, you could ask your hosting provider to provide at least the debug messages so you would be able to debug what's wrong.
Or give up debugging and use another mail server/mail protocol/sending class.
Addition: It seems it's actually even documented that qmail doesn't accept \r\n, only \n. PHP Manual also states that
If messages are not received, try using a LF (\n) only. Some Unix mail
transfer agents (most notably qmail) replace LF by CRLF
automatically (which leads to doubling CR if CRLF is used). This
should be a last resort, as it does not comply with RFC 2822.

Start using Swiftmailer, your life will be easier.
Use example :
require_once('swift/lib/swift_required.php');
$transport = Swift_MailTransport::newInstance();
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance()
->setFrom(array($from))
->setTo(array($to))
->setEncoder(Swift_Encoding::get7BitEncoding())
->setSubject($subject)
->setBody($body, 'text/html')
->addPart(strip_tags($body), 'text/plain')
->attach(Swift_Attachment::fromPath($filename))
;
$mailer->send($message);

Related

PHP mail() works randomly? [duplicate]

This question already has answers here:
PHP mail function doesn't complete sending of e-mail
(31 answers)
Closed 4 years ago.
So I have a normal but long HTML form on this page
The PHP mail script for the form is:-
$to = "something#gmail.com";
$from = $_POST['contact_email'];
$subject = "Application form submission";
$message = "<h2>Tell us what you need?</h2>";
$message .= "Loan Amount Required ?";
$message .= "<br>";
$message .= $_POST['tell_loan_amount'];
$message .= "<br>";
$message .= "<br>";
$message .= "What For?";
$message .= "<br>";
$message .= $_POST['tell_what_for'];
/* and so on */
$headers = "From: $from" . "\r\n" ;
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html; charset: utf8\r\n";
$headers .= 'X-Mailer: PHP/' . phpversion();
if( mail($to,$subject,$message,$headers)) {
echo "<h1>Thank you for the Application</h1>";
echo "<p>We will now review the application. This process normally takes 2-3 Business Hours. If we need to discuss any aspect of the application we will contact you. If you have any questions at all please do not hesitate to contact us on <strong>1300 815 462</strong></p>";
}
else {
echo "failed";
}
Now the problem is that mail only gets sent sometimes. I have had several clients contact and said that they successfully reached the thank you page and received the success message but we never received the mail. And yes, not in Spam either.
Is it happening because it is set to gmail?
Or is it happening because of incorrect encoding? (Our clients are filling form in English.)
Or do I need to use mb_send_mail() instead of mail() and remove the encoding code altogether?
use this command on you server it will output what happen to your sent mail :
tail -f /var/log/maillog
sometimes the provider block port 25

Correct method to output \' and other escape characters to HTML

I currently have a jquery function that has pre-written strings stored in them like this:
$('#message').val("Your parts have been ordered. We'll let you know when we receive the parts and begin installing them.");
When I click a button, it will take the string and fill it in a textarea to make filling out a form easier. It fills the textarea with the correct information and looks great on the actual form elements.
However when I'm sending the message to the client using PHPs mail function, at every ', ", and other special character it's inserting a \ before the character, so it will output like this:
Your parts have been ordered. We\'ll let you know when we receive the parts and begin installing them.
Is there a built in function that I can run the variables through before sending the email?
I've been doing some research and the closest thing I found is PHPs htmlspecialchars function, but this does the exact opposite of what I'm trying to accomplish.
Getting POST variable:
$commentmessage = mysqli_real_escape_string($conn, $_POST['message']);
Setting Headers for email (might be relevant because I'm formatting it using a table):
$headers = "From: Repairs#email.com \r\n";
$headers .= "Reply-To: ". $useremail . "\r\n";
$headers .= "CC: myemail#email.com \r\n";$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
Creating Message:
$emailmessage = wordwrap($emailmessage, 100, "\r\n");
$emailmessage = '<html><body>';
$emailmessage .= '<img src="imageurl" alt="Logo" />';
$emailmessage .= '<table rules="all" border="1" style="border-color: #666;" cellpadding="10">';
$emailmessage .= "<tr style='background: #eee;'><th colspan='2'><strong>" . $commentSubject ."</strong></th></tr>";
$emailmessage .= "<tr><td>" . $commentmessage . "</td></tr>";
$emailmessage .= "<tr><td><b>Ticket #: </b>" . $ticketid . "</td></tr>";
$emailmessage .= "</table>";
$emailmessage .= "</body></html>";
// Send Mail By PHP Mail Function
if (mail($to, $subject, $emailmessage, $headers)) {
$message = "Your mail has been sent successfully!";
}
else {
$message = "Failed to send email, try again.";
}
For PHP you have a built-in function: stripslashes().

mail is not working, not sending out two emails

I have a script that recognizes the level and I have added alerts to let me know if I have passed through the code. The two email addresses are reflecting. I want to send out two emails seperately, but my inbox is not working. I have checked my junk mail.
Is there something that am i missing?
function emaillog($to,$id,$subject,$message){
include("dbconnect.php");
mysql_query("INSERT INTO emlog(mm,tt,ss,rr) VALUES('$message','$to','$subject','$id')");
}
if($level == 1){
$assignedtowho_email_result = mysql_query("SELECT Email FROM sheet1 WHERE id IN(SELECT assignedtowho FROM tbl_one WHERE id =$id)");
while($row_email=mysql_fetch_array($assignedtowho_email_result)){
$assignedtowho_email=$row_email['Email'];
}
// Email Sending department
$to = $senderEmail;
$subject = "Refferal status updated by recieving r";
$message = "Your status has been updated by ";
$from = "info#test.co.za";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
emaillog($to,$id,$subject,$message);
$message_alert="Sender mail sent: ".$to;
echo '<script>alert("'.$message_alert.'")</script>';
//echo "Mail Sent.";
// Email Recieving department
$to = $assignedtowho_email;
$subject = "Refferal status updated ";
$message = "Your refferal status has been updated";
$from = "info#test.co.za";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
emaillog($to,$id,$subject,$message);
$message_alert_2="Assigned mail sent: ".$to;
echo '<script>alert("'.$message_alert_2.'")</script>';
//echo "Mail Sent.";
}
Requirements
For the Mail functions to be available, PHP must have access to the sendmail binary on your system during compile time. If you use another mail program, such as qmail or postfix, be sure to use the appropriate sendmail wrappers that come with them. PHP will first look for sendmail in your PATH, and then in the following: /usr/bin:/usr/sbin:/usr/etc:/etc:/usr/ucblib:/usr/lib. It's highly recommended to have sendmail available from your PATH. Also, the user that compiled PHP must have permission to access the sendmail binary.
http://tr2.php.net/manual/en/mail.requirements.php
Be sure you have all requirements and SMTP server.
Therefore, mail() function prop. can change depends on your OS and PHP version
You can see all of this [here][1]
in ChangeLog side.
If you are using Windows , you must use PEAR Mail . İt's here
For Linux OS such as Ubuntu and Centos , you must be sure configure php.ini and apache/httpd.ini
You use this for on every OS
<?php # Is the OS Windows or Mac or Linux
if (strtoupper(substr(PHP_OS,0,3)=='WIN')) {
$eol="\r\n";
} elseif (strtoupper(substr(PHP_OS,0,3)=='MAC')) {
$eol="\r";
} else {
$eol="\n";
} ?>
<?php
# File for Attachment
$f_name="../../letters/".$letter; // use relative path OR ELSE big headaches. $letter is my file for attaching.
$handle=fopen($f_name, 'rb');
$f_contents=fread($handle, filesize($f_name));
$f_contents=chunk_split(base64_encode($f_contents)); //Encode The Data For Transition using base64_encode();
$f_type=filetype($f_name);
fclose($handle);
# To Email Address
$emailaddress="user#example.com";
# Message Subject
$emailsubject="Heres An Email with a PDF".date("Y/m/d H:i:s");
# Message Body
ob_start();
require("emailbody.php"); // i made a simple & pretty page for showing in the email
$body=ob_get_contents(); ob_end_clean();
# Common Headers
$headers .= 'From: Jonny <jon#example.com>'.$eol;
$headers .= 'Reply-To: Jonny <jon#example.com>'.$eol;
$headers .= 'Return-Path: Jonny <jon#example.com>'.$eol; // these two to set reply address
$headers .= "Message-ID:<".$now." TheSystem#".$_SERVER['SERVER_NAME'].">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol; // These two to help avoid spam-filters
# Boundry for marking the split & Multitype Headers
$mime_boundary=md5(time());
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/related; boundary=\"".$mime_boundary."\"".$eol;
$msg = "";
# Attachment
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: application/pdf; name=\"".$letter."\"".$eol; // sometimes i have to send MS Word, use 'msword' instead of 'pdf'
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Disposition: attachment; filename=\"".$letter."\"".$eol.$eol; // !! This line needs TWO end of lines !! IMPORTANT !!
$msg .= $f_contents.$eol.$eol;
# Setup for text OR html
$msg .= "Content-Type: multipart/alternative".$eol;
# Text Version
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/plain; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= "This is a multi-part message in MIME format.".$eol;
$msg .= "If you are reading this, please update your email-reading-software.".$eol;
$msg .= "+ + Text Only Email from Genius Jon + +".$eol.$eol;
# HTML Version
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= $body.$eol.$eol;
# Finished
$msg .= "--".$mime_boundary."--".$eol.$eol; // finish with two eol's for better security. see Injection.
# SEND THE EMAIL
ini_set(sendmail_from,'from#example.com'); // the INI lines are to force the From Address to be used !
mail($emailaddress, $emailsubject, $msg, $headers);
ini_restore(sendmail_from);
?>

php mail function not getting the emails

ok, so I put together a very basic mail function and while testing this, I used a couple of email accounts, one my google account and the other my work account. I get all emails at the google account, but not to those pointing at my work. I'm thinking that could be because they have been caught up with the anti-spam software. Any ideas on how can I develop the mail function to avoid being caught on with spam software?
Here is a copy of my mail function
$to = 'account#gmail.com';
$subject = 'The subject';
$message = 'Hello,'."\n";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
$headers = 'From: me#mycompnay.com' . "\r\n" .
'CC: anotherone#mycompany.com' . "\r\n";
$mail_sent = mail($to, $subject, $message, $headers);
if($mail_sent) {
header("location:newlocation.php");
}
}
A lot of times this has less to do with PHP's mail() function and much more to do with the configuration of your mail transport agent. A lot of mail servers will bounce messages they assume are from spammers (i.e. unconfigured/misconfigured senders) before they even get passed to a spam filter.
If you check your MTA's logs you'll probably find some bounce messages the likes of, "Mail from this server not allowed, see blacklist info at [insert url].
Spam filters use a lot of different methods to determine if the mail coming in is actually spam or not.
Here are a few things that I would suggest:
Descriptive subject line
Descriptive message, careful with HTML and other rich content inside the body as sometimes spam filters will pick up on it as an "advertisement".
Full complete headers with realistic information in there as much as possible.
Try experimenting with different combination's and see if you can get one through to your work. The good thing is that your google account got the e-mail so you know its not an server side issue locally.
you probably need to format your headers and content properly. boundaries are missing.
Here's one simple function with HTML formatting mail:
<?php
function html_mail($i){
$to = $i['to'];
$to_name = $i['to-name'];
$subject = $i['subject'];
$html_message = $i['message'];
$from = $i['from'];
$from_name = $i['from-name'];
$reply_to = $i['reply-to'];
$reply_to_name = $i['reply-to-name'];
if(!$to || !validate::email($to)){return false;}
$email_message = '';
$email_subject = $subject;$email_txt = $html_message;
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
$email_to = ($to_name ? $to_name.'<'.$to.'>':$to);
$headers = "From: ".($from_name!='' ? $from_name.'<'.$from.'>':$from)."\n";
if($reply_to){
$headers .= "Reply-To: ".($reply_to_name ? $reply_to_name.'<'.$reply_to.'>':$reply_to)."\n";
}
$headers .= "MIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;" .
" boundary=\"{$mime_boundary}\"";
$email_message .= "This is a multi-part message in MIME format.\n\n";
$email_message .= "--{$mime_boundary}\n";
$email_message .= "Content-Type: text/html; charset=utf-8\n";
$email_message .= "Content-Transfer-Encoding: 8bit\n\n";
$email_message .= $email_txt;
$email_message .= "\n\n";
$email_message .= "--{$mime_boundary}\n";
$email_message .= "Content-Type: text/plain; charset=utf-8\n";
$email_message .= "Content-Transfer-Encoding: 8bit\n\n";
$email_message .= trim(strip_tags(str_replace(array('<br/>','<br />','<br/>'),"\r\n",$email_txt)));
$email_message .= "\n\n";
$email_message .= "--{$mime_boundary}--";
$ok = #mail($email_to, $email_subject, $email_message, $headers);
return $ok;
}
?>
when you have a properly formatted mail, you probably will be able to by pass the filters.
Spam determination is entirely determined by the software that's running the spam heuristics. You would have to look into the anti-spam software that your company uses and see why it's being caught as spam. More often than not it has to do with your mail server set up. A key factor that a lot of software uses is a valid reverse DNS entry, so you could look into that.
You have to realize that if there was an easy way around anti-spam software catching your email as spam just by modifying a few headers, then anti-spam software would be entirely useless, since the spammers would know those methods as well.
Adding a valid 'from' header would be the first thing to do, I think.
and thank you very much for all your suggestions. I found the answer on this post
How to change envelope from address using PHP mail?
It worked.
L.

PHP mail() attachment is corrupt

I have been struggling with trying to send an email with an attachment using PHP. It used to work but the message body was scrambled. Now I have got the message body to work but the attachment corrupts. I used to use base64 encoding for the message body but now use 7bit. Can anyone tell me what I am doing wrong?
PS please do not tell me that I should be using a pre-made class to do this. I have tried several and they have all failed to work. If I do not overcome these problems I will never learn how to do it properly. Thanks
//define the receiver of the email
$to = 'a#something.co.uk';
//define the subject of the email
$subject = 'Your Disneyland Paris entry';
//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date('r', time()));
//define the headers we want passed. Note that they are separated with \n
$mime_boundary = "<<<--==+X[".md5(time())."]";
$path = $_SERVER['DOCUMENT_ROOT'].'/two/php/';
$fileContent = chunk_split(base64_encode(file_get_contents($path.'CTF_brochure.pdf')));
$headers .= "From: info#blah.org.uk <info#blah.org.uk>"."\n";
$headers .= "MIME-Version: 1.0\n" .
"Content-Type: multipart/mixed;\n" .
" boundary=\"{$mime_boundary}\"";
$message = "This is a multi-part message in MIME format.\n";
$message .= "\n";
$message .= "--".$mime_boundary."\n";
$message .= "Content-Type: text/plain; charset=\"iso-8859-1\"\n";
$message .= "Content-Transfer-Encoding: 7bit\n";
$message .= "\n";
$message .= "messagebody \n";
$message .= "--".$mime_boundary."" . "\n";
$message .= "Content-Type: application/octet-stream;\n";
$message .= " name=\"CTF-brochure.pdf\"" . "\n";
$message .= "Content-Transfer-Encoding: 7bit \n";
$message .= "Content-Disposition: attachment;\n";
$message .= " filename=\"CTF_brochure.pdf\"\n";
$message .= "\n";
$message .= $fileContent;
$message .= "\n";
$message .= "--".$mime_boundary."--\n";
//send the email
$mail_sent = mail($to, $subject, $message, $headers);
//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed"
echo $mail_sent ? "Mail sent" : "Mail failed";
I could be wrong but I believe you will have to encode the PDF somehow, 7bit won't work as the PDF file will have content outside the range. Why not use base64 for the PDF?
I would suggest looking at phpmailer if you want to do complex email.
I know you've said about pre-built classes but there is a reason that people do this - why re-invent the wheel? I use SwiftMailer for projects - it couldn't be simpler. See this SwiftMailer example for 13 lines (including some blank ones) of how to create a message, add an attachment and send.
As to the resolution of your actual query, upvote to Josh's answer - I'd second changing the encoding and seeing how you get on. Have you tried getting an example email message which has an attachment that works, and examining the raw data?

Categories