1

I'm configuring a Magento 1.9.1 to use an external SMTP to send emails, using SMTP PRO (https://www.magentocommerce.com/magento-connect/smtp-pro-email-free-custom-smtp-email.html).

I've setup the configuration (hostname, port, username, password) but when I try to send a test email it fails with a 'Could not open socket' error message. If I dig into the code I see that the error is generated from this piece of code in lib/Zend/Mail/Protocol/Abstract.php:

$this->_socket = @stream_socket_client($remote, $errorNum, $errorStr, self::TIMEOUT_CONNECTION);

        if ($this->_socket === false) {
            if ($errorNum == 0) {
                $errorStr = $remote.' Could not open socket '.phpversion();
            }
            /**
             * @see Zend_Mail_Protocol_Exception
             */
            #require_once 'Zend/Mail/Protocol/Exception.php';
            throw new Zend_Mail_Protocol_Exception($errorStr);
        }

My PHP environment (5.6.30) has openssl support (see image and snippet below) SSL Support

[root@ns3023903 httpdocs]# php -r 'print_r(stream_get_transports());'
Array
(
    [0] => tcp
    [1] => udp
    [2] => unix
    [3] => udg
    [4] => ssl
    [5] => sslv3
    [6] => sslv2
    [7] => tls
)

There are no firewall issues as i can both telnet on the port 465 to the target host or send an email using the same SMTP using phpmailer with the same user I use to run the site virtualhost.

I'm on a CentOS 7 64 bit server, with SELinux disabled and, if that matters, I'm using Plesk 12 to configure virtual hosts.

Name resolution is also working ok (I can ping the SMTP name correctly and the IP address is looked up just fine).

I'm obviously missing something here...but what?

1 Answer 1

3

It turned out it was something that changed in the PHP version 5.6.30, in terms of default options assumed by stream_socket_client().

First of all before getting rid of the stupid @ in front of the stream_socket_client call in the Magento core code I wasn't actually able to understand what was going on. I'm not even close to a PHP developer so I keep forgotting what that stupid @ prefix is for (to be honest I don't even know why it exists).

After removing the @ I saw this:

Warning: stream_socket_client(): Peer certificate CN=`*.aruba.it' did not match expected CN=`mail.myclientreserveddomain.com'

I looked a bit into the PHP documentation and I came out with a two line diff to the core code (I know this is not right, I'll refactor it now, but I wanted to share the quick workaround first).

Basically I'm creating a context and using another version of the stream_socket_client call

 $context = stream_context_create(['ssl' => [
    'verify_peer' => false,
    'verify_peer_name' => false
    ]]);
// open connection
$this->_socket = stream_socket_client($remote, $errorNum, $errorStr, 120, STREAM_CLIENT_CONNECT, $context); 

Skipping peer name validation is the key. Not sure why/how/when it changed from php pre 5.6.30 to PHP 5.6.30 (have I said I'm not a PHP dev?) but it works. I also tried to run the original code under PHP 5.4.x and it worked without the workaround so it's definitely that.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.