horst

WireMailSmtp

Recommended Posts

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?

Share this post


Link to post
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);
 

Share this post


Link to post
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

 

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Hi,

it is possible to set the WireMailSmtp config settings at runtime and send email using different settings for each user?

Thank you

Share this post


Link to post
Share on other sites

Yes you can read and write modules config data via PWs API for all modules. Please refer to the docs, or search the forum via google for something like $modules->get("WireMailSMTP")-> getConfigData(), or readConfigData() ? and ->writeConfigData($data).

Sorry, I'm on mobile and cannot provide links or exact code snippets ATM. :)

----

EDIT:

you can use this:

$data = wire('modules')->getModuleConfigData("WireMailSmtp");

// or, regarding on scope,
$data = $modules->getModuleConfigData("WireMailSmtp");

after modifying, you can write it back:

wire('modules')->saveModuleConfigData("WireMailSmtp", $data);

// or

$modules->saveModuleConfigData("WireMailSmtp", $data);

Edited by horst
added code snippets
  • Like 1

Share this post


Link to post
Share on other sites

I wonder if someone could give me an idea how to use the attachment aspect to WireMailSmtp? I am doing a simple form that allows the upload of pdf's only. I am unsure how to access the file size, type, etc. so that I can sanitize things a bit.

Thanks in advance.

Edited by kongondo
No need to start a new topic for a module that has its own support forum + have a look at page 1 of this thread

Share this post


Link to post
Share on other sites

Thanks Kongondo. By the way, page 1 doesn't answer this question (unless I am being a complete dunce!)

It does:

attachment ($filename) - add attachment file(s) - string or array()

$mail = wireMail(); 
$mail->attachment($filename); // string $filename or array $filenames

what means: you can add any single file path as a string with the attachment() method, or you can add multiple files at once with its pathes stored in an array.

Everything else, e.g. how you submit your form and / or upload the files, does not belong to WireMailSmtp. For this, you may find information and examples on php.net. :)

Edited by horst
  • Like 2

Share this post


Link to post
Share on other sites

Attachments work very well using this mailer. I'm using it to send out event photos to purchasers - nice, nice, nice. Thanks for the work on this, Horst!

Share this post


Link to post
Share on other sites

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


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Robin S
      An experimental module for adding images to a field via pasting one or more URLs.
      Add Image URLs
      Allows images to be added to an images field by pasting URLs.

      Usage
      Install the Add Image URLs module.
      A "Paste URLs" button will be added to all image fields. Use the button to show a textarea where image URLs may be pasted, one per line. Images are added when the page is saved.
       
      https://github.com/Toutouwai/AddImageUrls
    • By netcarver
      This module provides a very simple interface to a set of named counters. You simply call a single function, next('name'), to pull the next value out of a counter - or to set it up if it does not yet exist. Next() takes a few extra parameters to allow you to increment by values other than 1 or to start at a certain number.
      This provides some similar functionality to the built-in page naming feature of PW, and to this module recently posted by Stikki but I think it offers a little more flexibility than either. Having said that, I do like the simplicity of Stikki's new auto-increment module.
      Module Availability
      Here is my module on Github.
      Here it is in the module repository.
      Example Usage
      Here's how this module can be used to title and name a new page by adding a couple of simple hooks to site/ready.php. This example applies to new pages using a template called 'invoice' that can be quick-added to the page tree. In order to get the following to work, you must edit the template that will be the parent of the 'invoice' template and setup the template for children to "invoice" and set the "Name Format for Children" field to something other than the default blank value (I use  title  as my value.)
      <?php /** * Function to recognise our special template. */ function isInvoiceTemplate($template) { return ($template == 'invoice'); } /** * Pre-load the page title for invoice pages with a unique value * which includes a counter component. */ $pages->addHookBefore("Pages::setupNew", function($event) { $page = $event->arguments(0); $is_invoice = isInvoiceTemplate($page->template); $no_inv_num = $page->title == ''; if ($is_invoice && $no_inv_num) { $counter_name = 'WR-' . date('Y'); $number = $this->modules->get('DatabaseCounters')->next($counter_name, 10, 5000); $page->title = $counter_name . '-' . sprintf("%06u", $number); } }); /** * Prevent ProcessPageEdit from forcing an edit of the name if we got here * through a quickAdd from ProcessPageAdd. We can do this because we * preset the title field in the Pages::setupNew hook. */ $pages->addHookAfter("ProcessPageEdit::loadPage", function($event) { $page = $event->return; $is_invoice = isInvoiceTemplate($page->template); $is_temp = $page->hasStatus(Page::statusTemp); if ($is_invoice && $is_temp) { $page->removeStatus(Page::statusTemp); $event->return = $page; } }); Note, the above code + module is one direct solution to the problem posted here by RyanJ.


      Version History
      1.0.0 The initial release.
    • By flydev
      PulsewayPush
      Send "push" from ProcessWire to Pulseway.
       
      Description
      PulsewayPush simply send a push to a Pulseway instance. If you are using this module, you probably installed Pulseway on your mobile device: you will receive notification on your mobile.
      To get more information about Pulseway, please visit their website.
      Note
      They have a free plan which include 10 notifications (push) each day.
       
      Usage
      Install the PulsewayPush module.
      Then call the module where you like in your module/template code :
      <?php $modules->get("PulsewayPush")->push("The title", "The notification message.", "elevated"); ?>  
      Hookable function
      ___push() ___notify() (the two function do the same thing)
       
      Download
      Github:  https://github.com/flydev-fr/PulsewayPush Modules Directory: https://modules.processwire.com/modules/pulseway-push/  
      Examples of use case
      I needed for our work a system which send notification to mobile device in case of a client request immediate support. Pulseway was choosen because it is already used to monitor our infrastructure.
      An idea, you could use the free plan to monitor your blog or website regarding the number of failed logins attempts (hooking Login/Register?), the automated tool then block the attacker's IP with firewall rules and send you a notification.
       

       
      - - -
      2017-11-22: added the module to the modules directory
       
    • By cosmicsafari
      Hi all,
      Just wondering if its possible to just add some basic output to my modules config page.
      I was wanting to output a bulleted list of some information which I will be pulling from a third party.
      Retrieving the data is fine i'm just not sure how to output it to the config page?
      From what I can see in the link below, it only seems like you can append form items to the page.
      https://processwire.com/blog/posts/new-module-configuration-options/
    • By netcarver
      A very simple textformatter that was inspired by Diogo's RemoveHeight textformatter.
      This one strips the height from any images and either adds a custom class or adds a max-width:100% as an embedded style.
      Github: https://github.com/netcarver/TextformatterFluidImages
      PW Repo: here.