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 ukyo
      Call ProcessWire API Functions Inside STRING
      Github Repo
      Current status : BETA
      Each called method must return string value !
      I added all functions, but not tested all. I focused page(), page()->render and field properties (label, description and notes). I also tested some basic pages() api calls.
      Your API calls must start with { and must end with }. For use multiple arguments inside functions, separate arguments with ~ char.
      NOTE If you pass directly arguments to api {page(title)}, this call will check for requestedApiCall()->get(arguments).
      USAGE
      processString(string, page, language); Get page title <?php $str = "You are here : {page:title}"; echo processString($str); ?> Get page children render result <?php $str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.<hr>{page:render:children}"; echo processString($str); ?> Get homepage title <?php $str = "You can visit our <a hre='{pages(1):url}'>{pages:get(1):title}</a>"; echo processString($str); ?> Get title field label, description or notes <?php $str = "Our title field properties are : label: {label(title)} - description: {description(title)} - notes: {notes(title)}"; echo processString($str); ?> Multiple examples <?php $str = " <ul class='uk-list uk-list-striped'> <li><b>01: GET FIELD LABEL</b> <code>&#123;label(title)&#125;</code> <b>RESULT :</b> <code>{label(title)}</code></li> <li><b>02: GET FIELD LABEL WITH PREFIX</b> <code>&#123;label(title~=> )&#125;</code> <b>RESULT :</b> <code>{label(title~=> )}</code></li> <li><b>03: GET FIELD LABEL WITH SUFFIX</b> <code>&#123;label(title~~ <=)&#125;</code> <b>RESULT :</b> <code>{label(title~~ <=)}</code></li> <li><b>04: GET FIELD DESCRIPTION</b> <code>&#123;description(title)&#125;</code> <b>RESULT :</b> <code>{description(title)}</code><br> <li><b>05: GET FIELD DESCRIPTION WITH PREFIX</b> <code>&#123;description(title~=> )&#125;</code> <b>RESULT :</b> <code>{description(title~=> )}</code></li> <li><b>06: GET FIELD DESCRIPTION WITH SUFFIX</b> <code>&#123;description(title~~ <=)&#125;</code> <b>RESULT :</b> <code>{description(title~~ <=)}</code></li> <li><b>07: GET FIELD NOTES</b> <code>&#123;notes(title)&#125;</code> <b>RESULT :</b> <code>{notes(title)}</code><br> <li><b>08: GET FIELD NOTES WITH PREFIX</b> <code>&#123;notes(title~=> )&#125;</code> <b>RESULT :</b> <code>{notes(title~=> )}</code></li> <li><b>09: GET FIELD NOTES WITH SUFFIX</b> <code>&#123;notes(title~~ <=)&#125;</code> <b>RESULT :</b> <code>{notes(title~~ <=)}</code></li> <li><b>10: GET PAGE TITLE</b> <code>&#123;page(title)&#125;</code> <b>RESULT :</b> <code>{page(title)}</code></li> <li><b>11: GET PAGE TITLE</b> <code>&#123;page:title&#125;</code> <b>RESULT :</b> <code>{page:title}</code></li> <li><b>12: GET PAGE RENDER TITLE</b> <code>&#123;page:render:title&#125;</code> <b>RESULT :</b> <code>{page:render:title}</code></li> <li><b>12: GET HOMEPAGE TITLE</b> <code>&#123;pages:get(template=home):title&#125;</code> <b>RESULT :</b> <code>{pages:get(template=home):title}</code></li> <li><b>13: GET HOMEPAGE TEMPLATE ID</b> <code>&#123;pages:get(template=home):template:id&#125;</code> <b>RESULT :</b> <code>{pages:get(template=home):template:id}</code></li> </ul> "; echo processString($str); ?>
    • By Robin S
      This module corrects a few things that I find awkward about the "Add New Template" workflow in the PW admin. I opened a wishlist topic a while back because it would good to resolve some of these things in the core, but this module is a stopgap for now.
      Originally I was going to share these as a few standalone hooks, but decided to bundle them together in a configurable module instead. This module should be considered alpha until it has gone through some more testing.
      Add Template Enhancements
      Adds some efficiency enhancements when adding or cloning templates via admin.

      Features
      Derive template label from name: if you like to give each of your templates a label then this feature can save some time. When one or more new templates are added in admin a label is derived automatically from the name. There are options for underscore/hyphen replacement and capitalisation of the label. Edit template after add: when adding only a single template, the template is automatically opened for editing after it is added. Copy field contexts when cloning: this copies the field contexts (a.k.a. overrides such as column width, label and description) from the source template to the new template when using the "Duplicate/clone this template?" feature on the Advanced tab. Copy field contexts when duplicating fields: this copies the field contexts if you select the "Duplicate fields used by another template" option when adding a new template. Usage
      Install the Add Template Enhancements module.
      Configure the module settings according to what suits you.
       
      https://github.com/Toutouwai/AddTemplateEnhancements
    • By AAD Web Team
      Hi,
      I've put in a support request (as a followup on an existing one) for this but it's nearly 10pm Ryan's time, so I thought I'd ask on here just in case someone can help...
      Yesterday we purchased ProDrafts, but I couldn't get the key to validate. Every time I hit submit on the module settings screen the key would be removed from the field I entered it in, and then it would complain about the missing value. I put in a support request and Ryan responded last night. It turned out it was because we're behind a proxy/firewall. He gave me a fix to get around that issue - some code to go into admin.php. I put that code in and saved admin.php, but now I can't even get into our admin anymore!
      (Just to clarify, I took the code back out and saved admin.php but that made no difference. It's definitely not the new code causing the error.)
      The errors relate to a lack of permission on the ProDrafts module (see attached screenshot). We do have a key, but evidently the code Ryan gave me to add the key in via admin.php isn't taking effect before the error is thrown...?
      I tried removing the ProDrafts directory from the modules directory, but that hasn't helped.
      Is there a hook I can put in somewhere to tell it not to load ProDrafts at all, or not check the permissions? Or is there some way to manually uninstall it from the file system?
      Thanks!
      Margaret

    • By DaveP
      I just made a textformatter module that allows you to insert dummy content (lorem ipsum style) in text fields via shortcodes.
      Usage is simple - just type for example [dc3] into a textarea with this textformatter applied (plain textarea or CKEditor) and it will be replaced at runtime by 3 paragraphs of dummy content. It can also be used to populate text fields (for headings etc) using e.g. [dc4w]. This will produce 4 words (rather than paragraphs) at runtime.
      The actual content comes from an included 'dummytext.txt' file containing 50 paragraphs of 'Lorem ipsum' from lipsum.com. The 50 paragraphs is arbitrary - it could be 10 or 100 or anything in between, and the contents of that file can be changed for your own filler text if you wish.
      The slightly clever bit is that for any given page, the same content will be returned for the same tag, but the more paragraphs available in 'dummytext.txt', the less likely it is that two pages will get the same content (very roughly speaking - it's actually based on the page ID) so content selection is determinate rather than random, even though only the tags are saved to the db.
      Update
      Tags now work like this -
      [dc3] - Show 3 paragraphs ([dc:3], [dc3p] & [dc:3p] all do the same). [dc3-6] - Show 3 to 6 paragraphs randomly per page load ([dc:3-6], [dc3-6p] & [dc:3-6p] all do the same). [dc3w] - Show 3 words ([dc:3w] does the same). [dc3-6w] - Show 3 to 6 words randomly per page load ([dc:3-6w] does the same). <End update on tags.>
      If you think it might be useful, you can download it from GitHub and give it a try.
    • By Robin S
      Password Generator
      Adds a password generator to InputfieldPassword.

       
      Usage
      Install the Password Generator module.
      Now any InputfieldPassword has a password generation feature. The settings for the generator are taken automatically from the settings* of the password field.
      *Settings not supported by the generator:
      Complexify: but generated passwords should still satisfy complexify settings in the recommended range. Banned words: but the generated passwords are random strings so actual words are unlikely to occur.  
      https://github.com/Toutouwai/PasswordGenerator