SMTP error when using $_ENV for credentials in PHPMailer - smtp

When using hard-coded username / email / password I have no problem getting a message sent with phpmailer. But when I use $_ENV to hide the credentials I get the smtp error as shown here:
2020-09-08 15:50:51 SERVER -> CLIENT: 220 dd45234.kasserver.com ESMTP
2020-09-08 15:50:51 CLIENT -> SERVER: EHLO browsegenres-f3.loc
2020-09-08 15:50:51 SERVER -> CLIENT: 250-dd45234.kasserver.com250-PIPELINING250-SIZE 102400000250-VRFY250-ETRN250-STARTTLS250-AUTH PLAIN LOGIN250-AUTH=PLAIN LOGIN250-ENHANCEDSTATUSCODES250-8BITMIME250 DSN
2020-09-08 15:50:51 CLIENT -> SERVER: STARTTLS
2020-09-08 15:50:51 SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
2020-09-08 15:50:51 CLIENT -> SERVER: EHLO xxxxxxxxxxxxxxxxxxxx.loc
2020-09-08 15:50:51 SERVER -> CLIENT: 250-xxxxxxxx.[SERVER].com250-PIPELINING250-SIZE 102400000250-VRFY250-ETRN250-AUTH PLAIN LOGIN250-AUTH=PLAIN LOGIN250-ENHANCEDSTATUSCODES250-8BITMIME250 DSN
2020-09-08 15:50:51 CLIENT -> SERVER: AUTH LOGIN
2020-09-08 15:50:51 SERVER -> CLIENT: 334 VXNlcm5hbWU6
2020-09-08 15:50:51 CLIENT -> SERVER: [credentials hidden]
2020-09-08 15:50:53 SERVER -> CLIENT: 535 5.7.8 Error: authentication failed: VXNlcm5hbWU6
2020-09-08 15:50:53 SMTP ERROR: Username command failed: 535 5.7.8 Error: authentication failed: VXNlcm5hbWU6
SMTP Error: Could not authenticate.
2020-09-08 15:50:53 CLIENT -> SERVER: QUIT
2020-09-08 15:50:53 SERVER -> CLIENT: 221 2.0.0 Bye
SMTP Error: Could not authenticate.
Message could not be sent. Mailer Error: SMTP Error: Could not authenticate.
I don't wan to hardcode the credentials. Any idea how to get rid of this error?
Here's the code:
// initiate phpMailer
$mail = new PHPMailer(true);
// see config file
$mailSenderName = $_ENV['MAILER_CONTACT_USERNAME'];
$masterPassword = $_ENV['MAILER_CONTACT_PASSWORD'];
$masterEmail = $_ENV['MAILER_CONTACT_EMAIL'];
$recipient = $_ENV['MAILER_CONTACT_RECIPIENT'];
try {
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->isSMTP();
$mail->Host = 'xxxxxxx.[SERVER].com';
$mail->SMTPAuth = true;
$mail->Username = $masterEmail;
$mail->Password = $masterPassword;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 25;
//Recipients
$mail->setFrom('aaa#bbbbbbbbbbb.com', 'aabbcc');
$mail->addAddress('mmmmmmmmm#bbbbbbbbbbb.com');
// Content
$mail->isHTML(true);
$mail->Subject = 'Message Received (Contact Page)';
$emailbody =
'There is a new message from: <br>' .
'==================================== <br>' .
$senderName . '<br>' .
$senderEmail . '<br' .
'====================================' .
$message . '<br>' .
'====================================';
$mail->Body = $emailbody;
$mail->send();
// success, show thank you
$f3->reroute('/contact/thankyou'); //todo
} catch (\Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
Thanks!

Debug one thing at a time. There's no point in looking at error in your email when you know you know you have a problem before it ever gets that far. PHPMailer uses whatever you give it, so you need to be sure you're giving it the right thing.
You could reduce the code to debug in this case by cutting it back to:
var_dump($_ENV);
Once you know that you're setting the contents of $_ENV correctly (whether from real env vars, from a dotenv script, your php.ini config, etc), you can then start using the values in your email code.

After installing dotenv (vlucas) I simply didn't include it correctly in my ContactController. So that's why var_dump($_ENV) always resulted in NULL. I compared my settings with the other route, NewsletterController. The difference is that in this route I query the database and in the models constructor (where the db connection is set) I 'use' the dotenv class correctly, and that's why the $_ENV is filled with data. I simply didn't see it.
So, in ContactController I set:
use \Dotenv;
and after initialising phpmailer I added:
$mail = new PHPMailer(true);
$dotenv = Dotenv\Dotenv::createImmutable($_SERVER['DOCUMENT_ROOT']);
$dotenv->load();
Difference to Models class (database connection):
namespace Models;
use \Dotenv;
abstract class Model
{
protected $db;
public function __construct()
{
$dotenv = Dotenv\Dotenv::createImmutable($_SERVER['DOCUMENT_ROOT']);
$dotenv->load();
$this->db = new \DB\SQL(
'mysql:host='. $_ENV['DB_HOST'] .';port='.$_ENV['DB_PORT'].';dbname='.$_ENV['DB_NAME'],
$_ENV['DB_USERNAME'],
$_ENV['DB_PASSWORD']
);
}
}

Related

PHPMailer Connects but not sending (Google XOAUTH2)

Can anyone interpret the following output from PHPMailer and diagnose the problem? I have successfully tested my code in isolation but after incorporating into an application it fails
2021-08-19 14:25:31 3 Connection: opening to ssl://smtp.gmail.com:465, timeout=300, options=array()
2021-08-19 14:25:31 3 Connection: opened
2021-08-19 14:25:31 2 SERVER -> CLIENT: 220 smtp.gmail.com ESMTP q184sm1663611qkd.35 - gsmtp
2021-08-19 14:25:31 1 CLIENT -> SERVER: EHLO localhost
2021-08-19 14:25:31 2 SERVER -> CLIENT: 250-smtp.gmail.com at your service, [2607:fea8:e2c0:5dd:6c0a:3ddc:897:57d9]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
2021-08-19 14:25:31
2021-08-19 14:25:31 1 CLIENT -> SERVER: QUIT
2021-08-19 14:25:32 2 SERVER -> CLIENT: 221 2.0.0 closing connection q184sm1663611qkd.35 - gsmtp
2021-08-19 14:25:32 3 Connection: closed
The code is based on the XOAUTH2 example in the PHPMailer documentation. The essential function is here:
//Import PHPMailer classes into the global namespace
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\OAuth;
//Alias the League Google OAuth2 provider class
use League\OAuth2\Client\Provider\Google;
class MainController extends Controller
{
function sendPHPMail($to, $name, $reply, $subject, $body, $attach, $type) {
// This function sends an HTML email via Google's SMTP server using XOAUTH2
//Create a new PHPMailer instance
$mail = new PHPMailer();
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
//SMTP::DEBUG_OFF = off (for production use)
//SMTP::DEBUG_CLIENT = client messages
//SMTP::DEBUG_SERVER = client and server messages
$mail->SMTPDebug = SMTP::DEBUG_CONNECTION;
$mail->Debugoutput = function($str, $level) {
file_put_contents('smtp.txt', gmdate('Y-m-d H:i:s'). "\t$level\t$str\n", FILE_APPEND | LOCK_EX);
};
//Set the hostname of the mail server
$mail->Host = $this->f3->get('mailHost');
//Set the SMTP port number:
// - 465 for SMTP with implicit TLS, a.k.a. RFC8314 SMTPS or
// - 587 for SMTP+STARTTLS
$mail->Port = 465;
//Set the encryption mechanism to use:
// - SMTPS (implicit TLS on port 465) or
// - STARTTLS (explicit TLS on port 587)
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Set AuthType to use XOAUTH2
$mail->AuthType = 'XOAUTH2';
//Fill in authentication details here
//Either the gmail account owner, or the user that gave consent
$emailUser = $this->f3->get('mailUser');
$clientId = $this->f3->get('oauthClientID');
$clientSecret = $this->f3->get('oauthClientSecret');
// Refresh Token obtained by configuring and running get_oauth_token.php
// after setting up an app in Google Developer Console.
$refreshToken = $this->f3->get('oauthRefreshToken');
//Create a new OAuth2 provider instance
$provider = new Google(
[
'clientId' => $clientId,
'clientSecret' => $clientSecret,
]
);
//Pass the OAuth provider instance to PHPMailer
$mail->setOAuth(
new OAuth(
[
'provider' => $provider,
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'refreshToken' => $refreshToken,
'userName' => $emailUser,
]
)
);
//Set who the message is to be sent from
//For gmail, this generally needs to be the same as the user you logged in as
$mail->setFrom($emailUser, "Mississippi Valley Textile Museum");
$mail->addReplyTo($reply);
//Set who the message is to be sent to
$mail->addAddress($to, $name);
//Set the subject line
$mail->Subject = $subject;
//Set HTML message body, convert referenced images to embedded
//Specify a basic plain-text alternative body
$mail->CharSet = PHPMailer::CHARSET_UTF8;
$mail->msgHTML($body);
//Replace the plain text body with one created manually
$mail->AltBody = 'This email is HTML; enable HTML mail if you cannot see it.';
//Add attachment if specified
if ($attach) {
$mail->addStringAttachment($attach, "MVTM{$type}.pdf"); }
//send the message, catch and log errors
try {
return $mail->send();
} catch (phpmailerException $e) {
file_put_contents('smtp.txt', gmdate('Y-m-d H:i:s'). "\n$e->errorMessage\n", FILE_APPEND | LOCK_EX);
//Pretty error messages from PHPMailer
return false;
} catch (Exception $e) {
file_put_contents('smtp.txt', gmdate('Y-m-d H:i:s'). "\n$e->errorMessage\n", FILE_APPEND | LOCK_EX);
// error messages from anything else
return false;
}
}
It appears to get by the initial connection but not the actual transmission to the smtp server
Solved. OK, there is nothing wrong with my code as shown here. The problem was in my app config file which hold the ClientSecret and RefreshToken. I had used single rather than double quotes which caused an escape to be misinterpretted. 3 days wasted but lesson learned.

PHPMailer SMTP port 25 connection problem (10060) but same connection via Outlook successful

Hello to the community.
I have come across a strange problem with PHPMailer.
I am trying to connect via SMTP to a host without encryption (port 25) and although I am able to connect to the said host via Outlook, the PHPMailer connection attempt fails with the message (10060):
Connection: opening to webmail.ypa.gr:25, timeout=300, options=array()<br>
2020-07-21 05:34:34 Connection failed. Error #2: stream_socket_client(): unable to connect to webmail.ypa.gr:25 (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) [...]<br>
2020-07-21 05:34:34 SMTP ERROR: Failed to connect to server: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (10060)<br>
SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting<br>
The parameters (host/port given by the server admins) set to PHPMailer ($EMAIL_CREDENTIALS) are dumped below.
array(9) {
["SMTP_HOST"]=>
string(14) "webmail.ypa.gr"
["SMTP_PORT"]=>
int(25)
["SMTP_AUTH"]=>
bool(true)
["SMTP_SECURE"]=>
bool(false)
["SMTP_AUTOTLS"]=>
bool(false)
["USERNAME"]=>
string(12) "..."
["PWD"]=>
string(6) "..."
["SENDER"]=>
string(12) "..."
["RECEIVER"]=>
string(12) "..."
}
This is the code snippet:
$mail = new PHPMailer(true);
var_dump($EMAIL_CREDENTIALS);
try
{
$mail->isSMTP();
$mail->SMTPDebug = 4;
$mail->Host = $EMAIL_CREDENTIALS["SMTP_HOST"];
$mail->Port = $EMAIL_CREDENTIALS["SMTP_PORT"];
$mail->SMTPAuth = $EMAIL_CREDENTIALS["SMTP_AUTH"];
$mail->SMTPSecure = $EMAIL_CREDENTIALS["SMTP_SECURE"];
$mail->SMTPAutoTLS = $EMAIL_CREDENTIALS["SMTP_AUTOTLS"];
$mail->Username = $EMAIL_CREDENTIALS["USERNAME"];
$mail->Password = $EMAIL_CREDENTIALS["PWD"];
$mail->setFrom($EMAIL_CREDENTIALS["SENDER"], "...");
$mail->addAddress($to);
$mail->Subject = $subject;
$mail->msgHTML($body);
$mail->send();
}
I have seen many answers to such problems but have not been able to fix it. Among others, I have explicitly disabled TLS.
Is there something else I can check?
Thank you.

EOF caught while checking if connected while using phpmailer

I've some problem trying to use phpmailer on my localhost.
I've been trying for at least 2 hours to connect my ionos 1&1 SMTP server using phpmailer.
<<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true); //Passing `true` enables exceptions
try {
//Server settings
$mail->SMTPDebug = 4; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.ionos.fr'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'mymail#mymail.fr'; // SMTP username
$mail->Password = 'mypassword'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
//Recipients
$mail->setFrom('anyrecipient#test.fr', 'Test');
$mail->addAddress('realadress#gmail.com', 'Joe User'); // Add a recipient
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo '<br>' . 'Message could not be sent. Mailer Error: ', $mail->ErrorInfo;
}
?>
In fact, here is the error logs:
<2019-01-02 09:02:04 Connection: opening to smtp.ionos.fr:465,
timeout=300, options=array() 2019-01-02 09:02:04 Connection: opened
2019-01-02 09:02:15 SMTP INBOUND: "" 2019-01-02 09:02:15 SERVER ->
CLIENT: 2019-01-02 09:02:15 SMTP NOTICE: EOF caught while checking if
connected 2019-01-02 09:02:15 Connection: closed SMTP Error: Could not
connect to SMTP host. SMTP Error: Could not connect to SMTP host.
Message could not be sent. Mailer Error: SMTP Error: Could not connect
to SMTP host.
Any advise/clue?
Thanks a lot.
Read the docs & examples. You’re using SMTPSecure = 'tls' With Port = 465. It’s very well documented that that combination will not work. Either change to ssl or port 587, but not both.

Postfix Mail Server on Webmin. Failed to connect to server, permission denied(13)

I used PHPMailer to send out email and it work perfectly fine on localhost. However, as client requested, we have to upload everything onto webmin. The PostFix Mail Server was being installed for us. The problem is that I could not get the email function to work on the server.
Here are my codes.
<?php
require_once('class.phpmailer.php');
$mail = new PHPMailer();
$body = 'Test Email';
$mail->IsSMTP(); // telling the class to use SMTP
$mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
// 1 = errors and messages
// 2 = messages only
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "smtp.xxx.xxx.xx";
$mail->Port = 25; // set the SMTP port for the GMAIL server
$mail->Username = "";
$mail->Password = "";
$mail->SMTPSecure = 'tsl';
$mail->SetFrom('support#xxx.xxx', 'Support');
$mail->Subject = "PHPMailer Test Subject via smtp, basic with authentication";
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
$mail->MsgHTML($body);
$address = "xxx#hotmail.com";
$mail->AddAddress($address, "Sara Chan");
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
?>
Error message:
SMTP ERROR: Failed to connect to server: Permission denied (13) SMTP connect() failed. Mailer Error: SMTP connect() failed.
I have tried configuring the postfix main.cf file, but it still does not work.
I've tried:
http://postfix.state-of-mind.de/patrick.koetter/smtpauth/postfix_configuration.html
http://www.postfix.org/BASIC_CONFIGURATION_README.html
http://wiki.centos.org/HowTos/postfix
http://www.postfix.org/STANDARD_CONFIGURATION_README.html#null_client
Configuration from these links are different. I'm a new PHP programmer (Still an undergraduate student), and all these are really confusing. Right now, my postfix main.cf is back to its 'default' state. What should I do now?
It looks like you're using an old version of PHPMailer, so update that.
If you're sending from the same server as your script (which it sounds like you are since you're configuring postfix), don't use SMTP, call the IsMail() or IsSendmail() function instead of IsSMTP().
There's no such SMTP secure mode as 'tsl' - you're thinking of 'tls', and if you were going to use that it would probably be on port 587 rather than 25.
You won't need to supply auth credentials if you're sending via mail or sendmail.
I had the same error on a Oracle Linux 7.7 server and solved it by entering the following commands:
sudo setsebool -P httpd_can_sendmail 1
sudo setsebool -P httpd_can_network_connect 1

Phpmailer SMTP 500 Error

I am getting error message when using phpmailer smtp function. I am using php5 and below is the code I used.
require_once("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPDebug = 1;
$mail->SMTPAuth = true;
$mail->Host = 'mail.mydomain.com';
$mail->Port = 21;
$mail->Username = xxx;
$mail->Password = xxx;
$mail->SetFrom($email, $firstname . " " . $lastname);
$mail->AddAddress($contact);
$mail->Subject = $subject;
$mail->Body = $message;
$mail->WordWrap = 50;
$mail->isHTML(true);
$mail->Send();
if(!$mail->Send())
{
echo "email_has_not_been_sent <br><br>";
echo "Mailer Error: " . $mail->ErrorInfo;
$IsSent = 0;
exit;
}
here are the error messages.
SMTP -> ERROR: EHLO not accepted from server: 500 EHLO not understood
SMTP -> ERROR: HELO not accepted from server: 500 HELO not understood
SMTP -> ERROR: AUTH not accepted from server: 500 AUTH not understood
SMTP -> ERROR: RSET failed: 500 RSET not understood
SMTP Error: Could not authenticate. SMTP -> ERROR: MAIL not accepted from server: 500 MAIL not understood
your code looks ok, but I think you're using a port more commonly used for FTP... 25 and 587 are more commonly used as SMTP ports
Some basic telneting should tell you what's going on:
telnet smtp.gmail.com 587
then enter the command EHLO and you will see the welcome message of the gmail SMTP server.
Now try that on your server and you'll see what you get
Then try the same for more common SMTP ports: 25 and 587 and you should see the difference.