Jump to content

WireMailSmtp


horst

Recommended Posts

Can you please provide some information regarding your setup for this website (versions of PHP/ProcessWire, type of hosting used, the hosting provider/or whether local hosted)?  Have you followed the instructions from your hosting provider regarding SMTP setup details, if not locally hosted?

It appears this code as part of smtp.php, generates a false positive in my case (no authentication required)

While the test fails, the module still sends mail correctly.

if($success
&& strlen($mechanism)==0)
{
   $this->error="it is not supported any of the authentication mechanisms required by the server";
   $success=0;
}

Commenting out $success will make the test pass, but probably not a good idea.

Nothing special about the hosting enviroment, as I said all email scripts, the normal wireMail() works, along with PHPMailer.

The issue is the SMTP server does not require authentication, which seems to be a requirement of the smtp.php as above, which in turn causes the test of the module to fail.

Link to comment
Share on other sites

+1 what cstevensjr said re Github.

Re the problem, it sounds like the module assumes some authentication will be required (not surprised that it assumes this, surprised there's SMTP services which don't require auth).

On a general note, this module providing as it does a way to send mail via Mandrill.com, has been a life saver for me. No more lost emails due to recipients email systems assuming an email from a tiny unknown host is spam (as Mandrill delivers millions of emails their reputation is superb and so emails invariably get to their destination w/o getting rejected).

  • Like 2
Link to comment
Share on other sites

Hey, you are all right. We have had another issue with authentication and the test, where the original SMTP-class also allowed the missing of authentication. In this regard, the user could successfully pass the test (connecting to the server, IP + Port) without providing authentication credentials.

Therefore I have hacked the original class with this code you have posted above. (assuming there will be no open relay servers out there in 2015) But yep, now you comes along here. :lol:

I will have a closer look to it and provide a better fix. (apropriate for both situations). In the meantime you can A) comment the part in the code, or B) don't use the test anymore on tis server.

Thanks for your help.

  • Like 1
Link to comment
Share on other sites

Have a look into Functions.php line 805, function wireMail():

	$mail = null; 
	$modules = wire('modules'); 

	// attempt to locate an installed module that overrides WireMail
	foreach($modules as $module) {
		$parents = class_parents("$module"); 
		if(in_array('WireMail', $parents) && $modules->isInstalled("$module")) { 
			$mail = wire('modules')->get("$module"); 
			break;
		}
	}
	// if no module found, default to WireMail
	if(is_null($mail)) $mail = new WireMail(); 

:lol:

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

I'm have some config problems with Wire Mail SMTP on a online website

My provider is One.com and after a online chat with the support, all my settings are correct: 

  • smtp hostname: send.one.com
  • smtp port 465
  • use SSL  yes
  • correct smtp user 
  • correct smtp password

With an email-client (Thunderbird) I get access, not with "Test settings now" of Wire Mail SMTP:

error:

  • ERROR: SMTP settings did not work
  • could not connect to the host "send.one.com": connection time out

Has anyone any idea?

Link to comment
Share on other sites

I'm have some config problems with Wire Mail SMTP on a online website

My provider is One.com and after a online chat with the support, all my settings are correct: 

  • smtp hostname: send.one.com
  • smtp port 465
  • use SSL  yes
  • correct smtp user 
  • correct smtp password

With an email-client (Thunderbird) I get access, not with "Test settings now" of Wire Mail SMTP:

error:

  • ERROR: SMTP settings did not work
  • could not connect to the host "send.one.com": connection time out

Has anyone any idea?

When you tried with the Thunderbird, was it on the same machine as the website is? Or the other way round: have you tried this settings and testconnection from an install on your localhost? If not, you also have to check if the server where your site is hosted has no outgoing firewall restrictions that get in your way.

If the install is on an online machine, you can use the php library here in the spoiler. I often use this for quick checks on hosting machines to see if I'm able to reach other machines, ports, services from there. It is a pure PHP lib to ping severs on specified ports with defined transports.

<?php
/*
    Author: Paul Aitken
    Creation Date: June 2003
    Contact: paul at phat-land com
    Class: Server Status
    Description: A class to check if certain service(s) are running

    Added functionality for checking via Gateways / Proxies
    by Horst Nogajski, January 2004
*/

// This code is Free for non-commercial use

class serverstatus
{
    // PUBLIC
    var $transport      = 'tcp';  // tcp udp ssl tls
    var $service;
    var $ip;
    var $port;
    var $local_ip         = 0;
    var $local_port     = 0;
    var $timeout;

    // PRIVATE
    var $errno;
    var $errstr;
    var $status;
    var $local_status     = TRUE;

    // CONSTRUCTOR: Can set Timeout
    function serverstatus($timeout=5)
    {
        $this->timeout = $timeout;
    }

    // PUBLIC: set Transport
    function set_Transport($t='tcp')
    {
        $valid = array('tcp','udp','ssl','tls','sslv2','sslv3'); // sslv3 ab PHP-5.0.2, alle anderen ab PHP-4.3.0
        if(in_array(strtolower($t),$valid))
        {
            $this->transport = $t;
        }
        else
        {
            $this->transport = 'tcp';
        }
    }

    // PUBLIC: Check Server
    function status_check($ip, $port, $service='', $local_ip=0, $local_port=0)
    {
        $this->service = $service;
        $this->ip = $ip;
        $this->port = $port;
        $this->local_ip = $local_ip;
        $this->local_port = $local_port;
        $this->local_status = TRUE;

        if($this->local_ip > 0 && $this->local_port > 0)
        {
            $this->local_status = FALSE;
            $this->check_local();
        }

        if($this->local_status)
        {
            $this->check_remote();
        }

        return $this->status;
    }

    // PUBLIC: Return Status
    function status_display($short=FALSE,$html=TRUE)
    {
        if(!$this->local_status)
        {
            // a local Gateway or Proxy which must be used is down!
            $filler = ' ';
            for($i=1;$i<10-strlen(trim($this->local_port));$i++) $filler.=' ';
            if($html)
            {
                return $short ? "-(<b>".$this->local_ip.":".$this->local_port."</b>) Gateway for ".$this->service." is <b>down</b>" : "- The local Gateway or Proxy for ".$this->service." is down, (".$this->local_ip.":".$this->local_port.")<br>\n";
            }
            else
            {
                return $short ? "- (".$this->local_ip.":".$this->local_port."){$filler}Gateway for ".$this->service." is down" : "- The local Gateway or Proxy for ".$this->service." is down, (".$this->local_ip.":".$this->local_port.")\r\n";
            }
        }
        else
        {
            $filler = ' ';
            for($i=1;$i<6-strlen(trim($this->port));$i++) $filler.=' ';
            if($this->status)
            {
                // It's TRUE (UP)
                if($html)
                {
                    return $short ? "+ (<b>".$this->port."</b>) ". $this->service." is <b>up</b>" : "+ The service <b>".$this->service."</b> is <b>up</b> and running. IP: <b>".$this->ip."</b> Port: <b>".$this->port."</b><BR>\n";
                }
                else
                {
                    return $short ? "+ UP   (".$this->port.")".$filler.$this->service : "+ The service ".$this->service." is up and running. IP: ".$this->ip." Port: ".$this->port."\r\n";
                }
            }
            else
            {
                // It's FALSE (DOWN)
                if($html)
                {
                    return $short ? "  (<b>".$this->port."</b>) ".$this->service." is <b>down</b>" : "- The service <b>".$this->service."</b> is currently <b>down</b>. IP: <b>".$this->ip."</b> Port: <b>".$this->port."</b><BR>\n";
                }
                else
                {
                    return $short ? "  DOWN (".$this->port.")".$filler.$this->service : "- The service ".$this->service." is currently down. IP: ".$this->ip." Port: ".$this->port."\r\n";
                }
            }
        }
        flush();
    }


    // PRIVATE: Check GATEWAY
    function check_local()
    {
        $this->local_status = ($sock = @fsockopen($this->transport.'://'.$this->local_ip, $this->local_port, $this->errno, $this->errstr, $this->timeout)) ? TRUE : FALSE;
        #if($sock!==FALSE) fclose($sock);
        $sock = NULL;
        unset($sock);
    }

    // PRIVATE: Check SERVER
    function check_remote()
    {
        $this->status = ($sock = @fsockopen($this->transport.'://'.$this->ip, $this->port, $this->errno, $this->errstr, $this->timeout)) ? TRUE : FALSE;
        #if($sock!==FALSE) fclose($sock);
        $sock = NULL;
        unset($sock);
    }

}



$ip = gethostbyname('send.one.com');
$port = 465;
$status = new serverstatus(20);
$status->set_Transport('ssl');  // you also can test / use: 'ssl','tls','sslv2','sslv3' 
$status->status_check($ip, $port, 'SMTP');
echo $status->status_display(false,false);
 
Link to comment
Share on other sites

My website is online, hosted by One.com, thunderbird is on my own machine

The spoiler-script  shows the message "The service SMTP is currently down. IP: adress  Port: 465". Thx horst for this excellent script. 

I had an hour chat with One.com Chat Support, where they suggested to change ports, SSL off, ...  (what I tried before).  Then I discoverd that SSL in my configuration panel was not activated.  The chat support said it must be activated, and after a few hours waiting, still the same error-messages.

thx cstevensjr, alan and horst, the search goes on

 
Link to comment
Share on other sites

If the script says the service is down, this only mean that it couldn't connect to the target server. So, when on the website server the outgoing request is blocked (firewall), this would also result in the same error message. If you have email / smtp accounts on other servers, e.g. gmail, hotmail or what ever, I suggest try to connect to them via the test script and see if it is possible.

And good luck! :)

  • Like 1
Link to comment
Share on other sites

Eureka, connection problem is solved

When a script is used for sending SMTP (One.com):

  • Server: NOT send.one.com  -> mailout.one.com
  • Port: 25
  • SSL: no
  • Authentication: no

With the 'spoiler-script' of Horst, no errors and in with my old website jusing AcyMailing (Joomla), it's also working fine now.

In Wire Mail SMTP, following error stays. I left SMTP user and SMTP is blank, but I assume that Wire Mail SMTP is always checking authentication??

  • server does not require authentication
  • ERROR: SMTP settings did not work
Link to comment
Share on other sites

  • 2 weeks later...

I've recently moved my website to another server and now wiremailsmtp doesn't work anymore, it display this message:
 

Warning: stream_socket_enable_crypto(): Peer certificate CN=`email-smtp.eu-west-1.amazonaws.com' did not match expected CN=`52.19.6.114' in /home/sodd/public_html/site/modules/WireMailSmtp/smtp_classes/smtp.php on line 1255

any idea? thanks

Link to comment
Share on other sites

It is a certificate that doesn't match. This has not directly to do with the module but with the server (certificate). An expected IP (52.19.6.114) doesn't match.

The IP (52.19.6.114) is mapped to the hostname "ec2-52-19-6-114.eu-west-1.compute.amazonaws.com"

and the hostname (email-smtp.eu-west-1.amazonaws.com) resolves to IP "52.30.192.168".

So this is something that you need to sort out with the hosting company.

  • Like 4
Link to comment
Share on other sites

  • 2 months later...

A small contribution:  Add an option to have ability to use Self-Signed Certificate on a given SMTP server with WireMailSmtp and PHP >= 5.6
 
What PHP say - source : https://secure.php.net/manual/en/migration56.openssl.php
 

Stream wrappers now verify peer certificates and host names by default when using SSL/TLS.

 
 
HOWTO:
-----------
 
1) In file smtp.php, class smtp_class, we add a member variable and a small function :

/* Allow self signed certificate */
var $smtp_certificate = false;
Function AllowSelfSignedCertificate($allow = false)
{
        $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7");
        $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]);
        if($php_version<5006000)
            return;
        if($allow) {
		stream_context_set_option($this->connection, 'ssl', 'verify_peer', false);
		stream_context_set_option($this->connection, 'ssl', 'allow_self_signed', true);
	}
	else
	{
		stream_context_set_option($this->connection, 'ssl', 'verify_peer', true);
		stream_context_set_option($this->connection, 'ssl', 'allow_self_signed', false);
	}
}

 
and, in the Connect() method, call the function just in before we check for the result of stream_socket_enable_crypto :
 
Find : 

$this->OutputDebug('Starting TLS cryptograpic protocol');
				
if(!($success = stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_TLS_CLIENT)))

Replace to

$this->OutputDebug('Starting TLS cryptograpic protocol');

$this->AllowSelfSignedCertificate($this->smtp_certificate);

if(!($success = stream_socket_enable_crypto($this->connection, 1, STREAM_CRYPTO_METHOD_TLS_CLIENT))

2) In the file smtp_message.php, class smtp_message_class, add a member variable :

/* Allow Self Signed Certificate */
var $smtp_certificate = 0;

In the method StartSendingMessage() , assign the new member variable:

$this->smtp->smtp_certificate = $this->smtp_certificate;

 
3) In the file WireMailSmtpAdaptator, class hnsmtp, add a member variable :

private $smtp_certificate   = false;

and in the method set_var_val(), add a case smtp_certificate for our checkbox :
Find :

case 'smtp_ssl':
case 'smtp_start_tls':
case 'smtp_debug':
case 'smtp_html_debug':

Replace :

case 'smtp_certificate':
case 'smtp_ssl':
case 'smtp_start_tls':
case 'smtp_debug':
case 'smtp_html_debug':

In the class constructor, add :

$this->emailMessage->smtp_certificate           = $this->smtp_certificate;

4) In the WireMailSmtpConfig.php file, add a field :
 
add : 

$field = $modules->get('InputfieldCheckbox');
$field->attr('name', 'smtp_certificate');
$field->label = __('PHP >= 5.6 - Allow self signed certificate');
$field->attr('value', $data['smtp_certificate']);
$field->attr('checked', $data['smtp_certificate'] ? 'checked' : '');
$fieldset->add($field);

5) In the WireMailSmtp.module file, add a settings to the getDefaultdata() :
Find :

'valid_recipients'         => ''     // email addresses of valid recipients. String that we convert to array at runtime.

Add after (take care of comma ','):

'smtp_certificate'		   => 0		  // allow or not self signed certificate (PHP >= 5.6)

 
Result :

1455460292-capture.png

Hope it help. Sorry for my english ^_^

  • Like 6
Link to comment
Share on other sites

@flydev: many thanks for your contribution, I have added it to the module by following your perfect guidance step by step. Very Nice. So, I have not tested it because I have no server with a Self-Signed Certificate at hand. But I very likely trust someones code who is able to contribute PHP code backwards compatible from PHP 5.6 to PHP 3.0! :lol:^-^

$version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7");
  • Like 3
Link to comment
Share on other sites

Cool !  but...  I forgot the following line in step 3, class hnsmtp; In the constructor we need to add

$this->emailMessage->smtp_certificate           = $this->smtp_certificate;

I edited my previous post containing the instructions.

Nice module and thanks for the update, I tested it right now and it work like a charm!

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...

Getting this error while sending mail and when testing settings (gmail) on dev verion 3.0.10. On localhost works fine, any idea? When uninstall wire mail smtp module, regular php wire mail works fine

SQLSTATE[HY000]: General error: 2006 MySQL

server has gone away

Link to comment
Share on other sites

Just wondering if anyone has tried this Module with MailGun?

I'm planning moving all my Mandarill App based settings to MailGun and at the moment mails are tested positive but no emails are recieved by me or even logged in my MailGun control panel.

Thanks

Link to comment
Share on other sites

  • SebastianP changed the title to Strange PHP error in WireMailSmtp: unexpected fully qualified name "\getmessage"

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...