PHPMailer SMTP connection timeout - wordpress

I've recently moved a Wordpress site from one server to another and I can no longer send mail via SMTP.
There is clearly somesort of network/resolver/credentials problem and I'm trying to debug it, but I've encountered some really unusual behaviour.
I'm looking at the connect method of the SMTP class. If I just try the code as it stands, then the line
$this->smtp_conn = #stream_socket_client(
$host . ":" . $port,
$errno,
$errstr,
$timeout,
STREAM_CLIENT_CONNECT,
$socket_context
);
causes a timeout. However if I add my own member variable eg protected $myvariable; and change the above code to assign the stream socket to $myvariable rather than smtp_conn, there is no time out.
If I check the unaltered code using var_dump on $this->smtp_conn just before trying to open the connection, it is NULL.
I've can't see any other code in PHPMailer which would effect the member variable $smtp_conn and I can't see how changing the name of a variable could stop the timeout.
Can anyone help me to debug this further.
================= EDIT =====================
I've discovered the assignment of $this->smtp_conn to the result of stream_socket_client causes the get_lines method to execute directly. That is, if I place an exit command directly after the assignment of $this->smtp_conn = stream_socket_client, the code in get_lines still runs.

Related

Do not print stack trace on Postfix's mail delivery failure notification

When our service fails to deliver an email, the rejection notification returned to the sender contains the stack trace of the code that failed. Is there a way to send the delivery notification, without the attached errors?
We have a postfix server that handles incoming emails in a catchall python script. That script uploads the email to one of our services and throws an exception in case it failed.
This is the template we are using
failure_template = <<EOF
Charset: us-ascii
From: MAILER-DAEMON (Mail Delivery System)
Subject: Undelivered Mail Returned to Sender
Postmaster-Subject: Postmaster Copy: Undelivered Mail
This is the mail system at host $myhostname.
I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.
For further assistance, please send mail to <postmaster>
If you do so, please include this problem report. You can
delete your own text from the attached returned message.
The mail system
EOF
Expected result would be just the template notification, without the strack trace of the catch-all script.
The mail server simply includes in the bounce whatever your Python program displays on its standard error. Maybe call the script via a wrapper which saves the standard error to a sane place (or even discards it, if you are sure it never contains anything useful).
#!/bin/sh
python3 /path/to/deliver.py 2>>/var/log/deliver.log
Your mail server obviously needs to have write access to the log, and you'll probably want to set up periodic log rotation for the file.
Probably a better overall approach is for the Python program to not crash.

CMIS connection issue

cannot tell if this issue is the same as some others posted. ours simply throws a msg, but it appears CMIS connection related - our application uses CMIS/Alfresco. i am not very familiar, but we have a server related to it. not sure if a power outage is related to the fact that we this error[pwr outage yesterday, then mysteriously this error was later noticed]. we normally post information on the web page that is populated by our sql data[a table field populates a textarea/text editor] - instead we get the error above: "CMIS connection issue". that verbiage comes from a file that instantiates connection with CMIS, here is the related code:
//Check cmis service connect or not
try{
$client = new CMISService($repo_url, $repo_username, $repo_password);
}catch (Exception $ec) {
echo "CMIS connection issue";
echo "<br >\n" ;
echo $ec->getMessage() ;
die;
}
the CMISService parms have not changed, and they appear to be proper values. i even tried "admin", and "root" as "repo_username" in addition to the defined username.
Ideas on what we can check?

Problems moving an web service to another server

I have C#/ASP.NET web service which is running on a remote server and uses WSDL. It worked fine up until recently when it was moved to another server. However this means I had to change the database connection string, which was hard coded, so the code needed to be rebuilt on my development machine and uploaded to the server.
The service is called from a PHP script running on another web server using SOAP.
For some reason, from what I can tell, it's trying to run the old code, even though I've modified it.
e.g. if I change my web service function to just return, for example, "Hello, World", it seems to still try to connect to the database, etc. (but failing because that database no longer exists, I believe it's still trying to use the old connection string)
If I remove the function, it tells me that the function doesn't exist. (So it is looking in the right place)
If I add a new function and try to call it from the php script, I get the error
The server did not recognize the value of HTTP Header SOAPAction
If I try and test it on the actual server using the http://localhost/Myservice/Myservice.asmx everything works fine!
Here is the code I am using to call:
ini_set("soap.wsdl_cache_enabled", 0);
$client = new SoapClient("http://1.2.3.4:8083/MyService/MyService.asmx?WSDL&revision=1", array('cache_wsdl' => WSDL_CACHE_NONE));
$input = new stdClass;
$input->inputvals = '15707F';
echo "Functions: |";
print_r($client->__getFunctions()); // Lists all functions including new ones
echo "|\n\n";
$Response = $client->checkPrice($input);
print_r($Response);
To deploy the code this is what I'm doing - on local development machine, I Publish the solution to File System (for some reason I can't get IIS working on this machine). Then stop IIS on server machine, "Remove Application" in IIS, copy my files in, "Convert to Application", then restart IIS.
The server seems to get a wrong SOAPAction HTTP-Head attribute (which is part of the SOAP-standard) from your SOAP-Client. Check the wsdl for the expected one (wsdl:binding section) and make sure that you're sending it with the expected value.
OK, I'm not completely satisfied with this solution but here is how I got it working.
I don't know enough about WSDL to know why or how this happens, but the WSDL xml file had the following lines in it (as per my comment on my own original post).
<wsdl:service name="Myservice">
<wsdl:port name="MyserviceSoap" binding="tns:MyserviceSoap">
<soap:address location="http://1.2.3.4/Myservice/Myservice.asmx" />
</wsdl:port>
.
.
.
</wsdl:service>
Note the lack of the :8083 port on the location. Originally I had moved the service from 1.2.3.4 to 1.2.3.4:8083 in order to keep it running during the transition - the router then uses NAT to forward it to the correct server on their internal network. When the owners of the server had said they turned off, all they had turned off was the MS SQL server on that computer, so my old web service was still working away. (I had kind of taken their word for it when they said they had turned off the server)
To work around this, I overrode the __doRequest() function in the SoapClient class in my PHP client script to manually add the :8083 to the URL of the location.
class SoapClient8083 extends SoapClient
{
public function __doRequest($request, $location, $action, $version, $one_way = 0) {
$location_parts = explode("//", $location);
if (count($location_parts) == 2) {
$location_url_parts = explode("/", $location_parts[1]);
$location_url_parts[0] .= ":8083";
$new_location = $location_parts[0] . "//" . implode("/", $location_url_parts);
}
if (isset($new_location) && $new_location)
$location = $new_location;
return parent::__doRequest($request, $location, $action, $version, $one_way);
}
}
So it was getting the function list from the correct place which was why it was correctly recognising when I removed the function, but then contacting the wrong place to actually implement the functions.
... 8 hours of trying to debug later ...
Anyway, I'd rather not stick with this solution and instead figure out why the WSDL doesn't put the port number on the <soap:address location... />
Thanks for the responses - they did encourage me to look in the right direction...

Postfix sendmail works from CL but not from PHP using Office365

I have been trying to use Office365 SMTP relay for a web server running postfix. I need to be able to send messages from my Office365 domain to other addresses in the domain, so I don't think port 25 anonymous SMTP is going to work.
If I run
echo "testing" | sendmail -fuser#mydomain.com me#mydomain.com
Then the message goes through (provided that user is listed in sasl_passwd)
However if I run a simple PHP script such as this:
<?php
$to = "me#mydomain.com";
$subject = "Test";
$message = "test from PHP";
$from = "user#mydomain.com";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
echo "Mail Sent.";
?>
Then the delivery is bounced with
550 5.7.1 Client does not have permissions to send as this sender
I have read that the empty from=<> value (which I can see in the logs) is the cause of the problem, but I don't understand how to change that to anything from postfix settings. Am I understanding correctly that postfix relay settings are correct if the command-line works? Is there some other step for PHP configuration that I am missing?
From looking at the log file, it appears as though two messages are generated each time the PHP script is run. One has the correct from address and the other is empty.
Let me know if you need any other information. Thanks in advance.
-Seth
Thanks to this other person (also answering their own question):
https://serverfault.com/questions/147921/forcing-the-from-address-when-postfix-relays-over-smtp/152126#152126
I am just posting this for anyone else who might stumble on my question.

Graceful recovery from policy file load failure

First off: This is not another question about how to load a policy file.
I have an app in development that connects to a socket server, gets the policy file and works just dandy. However, when the socket server is down for whatever reason, I need to gracefully fallback to an alternative method of getting messages from the server (polling, basically).
This is not a problem, except for one thing:
Error: Request for resource at xmlsocket://[ip]:4770 by requestor from http://[ip]/cooking/Client.swf has failed because the server cannot be reached.
There doesn't appear to be a way to catch this. I have these event listeners on my socket:
addEventListener(Event.CLOSE, closeHandler);
addEventListener(Event.CONNECT, connectHandler);
addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
SecurityErrorEvent is what you might think fires, but it doesn't. The docs say it fires for these reasons:
Local untrusted SWF files may not communicate with the Internet. You can work around this limitation by reclassifying the file as local-with-networking or as trusted.
You cannot specify a socket port
higher than 65535.
In the HTML page that contains the
SWF content, the allowNetworking
parameter of the object and embed
tags is set to "none".
So none of those apply. It appears what I really want to catch is the failure of the policy file to load, but even doing an explicit Security.loadPolicyFile() won't help, since that load is deferred to the first socket request AND doesn't fire any events.
For completeness, I also surrounded the call to connect() with a try{}catch (e:*){}, no result.
There's got to be a way to sort this. Any ideas? I simply need a way to tell when the connection has failed because of networking issues and try an alternate path.
EDIT: Despite my previous tests and the docs, it appears SecurityErrorEvent does fire - only it does it about 20 seconds after the load fails, so it's not obvious. I guess that's as immediate as I'm going to get from Flash.
Don't forget to retry connecting :)
private function onIOError(e:IOErrorEvent):void {
e.stopPropagation();
++this.retryCount;
if( this.retryCount >= 12 ){
this.connectTimer.stop();
this.dispatchEvent( new Event( 'TIMIEDOUT' ) );
}else{
this.err = 'IO-ERROR-EVENT - ' + e.text + '\r\nAttempting to reconnect';
}
}

Resources