Fork me on GitHub
Subscribe 5

Ticket #710 (fixed bug)

Error: Unable to send email. SMTP server: "501 Syntactically invalid EHLO argument(s) ".

  • Created: 2012-07-13 17:28:10
  • Reported by: Mr.Anderson
  • Assigned to: JohnLewis
  • Milestone: 1.5.1
  • Component: email
  • Priority: high

Hello,

I found a bug in 1.5.0, which prevents emails from being sent when using SMTP with an RFC compliant server.

Line 312 of include/email.php should be changed from

		fwrite($socket, 'EHLO '.$smtp_host."\r\n");

to

		// Here we try to determine the *real* hostname (reverse DNS entry preferrably)
		$local_host = 'localhost.localdomain';

		if (function_exists('php_uname'))
		{
			$local_host = php_uname('n');

			// Able to resolve name to IP
			if (($local_addr = @gethostbyname($local_host)) !== $local_host)
			{
				// Able to resolve IP back to name
				if (($local_name = @gethostbyaddr($local_addr)) !== $local_addr)
				{
					$local_host = $local_name;
				}
			}
		}

		fwrite($socket, 'EHLO '.$local_host."\r\n");

The reason for this change is, that the fully qualified domain name has to be given in the EHLO command (according to RFCs). Most ISPs nowadays deny or blackhole emails if no valid hostname (one that actually resolves) has been given here.

In SourceForge.net server which hosts my project the internal smtp_host is prwebmail and there is no FQDN available for it AFAIK. Unfortunately it won't accept prwebmail as EHLO reply. But it works great after the patch below.

Best Regards,

History

Mr.Anderson 2012-07-13 17:30:51

  • Description changed. (Diff)

Franz 2012-07-13 20:31:42

  • Milestone set to 1.5.1.
  • Priority changed from highest to high.

Thank you for the report.

JohnLewis 2012-09-12 15:54:18

  • Owner set to JohnLewis.

Implementing now, Just doing a quick test though.

Franz 2012-09-13 21:56:41

I am about to merge this, but what about this line a little further down:

fwrite($socket, 'HELO '.$smtp_host."\r\n");

Should that be changed to $local_host, too?

Cheers for the patch.

JohnLewis 2012-09-13 22:06:54

Commit 641f210 to fluxbb master

#710: Determine correct hostname when sending mails via SMTP.

Patch suggested by Mr. Anderson, thanks.
This merges pull request #49.

JohnLewis 2012-10-09 17:25:43

  • Status changed from open to fixed.

I will close this as fixed. It seems to function as it is and changing later code may or may not be a factory of function. If it appears it needs to be changed, it's a simple commit.

yoorick 2013-03-13 18:53:07

Franz wrote:

what about this line a little further down:

fwrite($socket, 'HELO '.$smtp_host."\r\n");

Should that be changed to $local_host, too?

Definitely should. Today I encountered a similar error message, but "501 Syntactically invalid HELO argument(s)".

But as I understand, originally the problem was that $smtp_host variable contains the address of a remote SMTP host, but according to RFC, HELO (and EHLO) must be used with your local host name.

3.2 Client Initiation
Once the server has sent the welcoming message and the client has received it, the client normally sends the EHLO command to the server, indicating the client's identity.
...
In the EHLO command the host sending the command identifies itself; the command may be interpreted as saying "Hello, I am <domain>" (and, in the case of EHLO, "and I support service extension requests").

And what really makes the problem in this case, is that this line

if ($pun_config['o_smtp_ssl'] == '1')
    $smtp_host = 'ssl://'.$smtp_host;

adds illegal characters to hostname that we send in HELO/EHLO message. So we get the error message.

JohnLewis 2013-03-13 18:58:44

  • Description changed. (Diff)

Done.

yoorick 2013-03-14 08:13:14

Thanks for quick reaction.
I've left my comment here.

yoorick 2013-03-14 18:23:22

And one more suggestion if you don't mind:

static $local_host;

if ($local_host === null)
{

    // Here we try to determine the *real* hostname (reverse DNS entry preferably)
    $local_host = php_uname('n');

    // Able to resolve name to IP
    if (($local_addr = @gethostbyname($local_host)) !== $local_host)
    {
        // Able to resolve IP back to name
        if (($local_name = @gethostbyaddr($local_addr)) !== $local_addr)
        {
            $local_host = $local_name;
        }
    }
}

if ($pun_config['o_smtp_user'] != '' && $pun_config['o_smtp_pass'] != '')
{
    fwrite($socket, 'EHLO '.$local_host."\r\n");
    server_parse($socket, '250');

    fwrite($socket, 'AUTH LOGIN'."\r\n");
    server_parse($socket, '334');

    fwrite($socket, base64_encode($pun_config['o_smtp_user'])."\r\n");
    server_parse($socket, '334');

    fwrite($socket, base64_encode($pun_config['o_smtp_pass'])."\r\n");
    server_parse($socket, '235');
}
else
{
    fwrite($socket, 'HELO '.$local_host."\r\n");
    server_parse($socket, '250');
}

Franz 2013-03-16 00:50:08

Too tired right now: why and where would that belong?

yoorick 2013-03-16 01:36:03

It is $local_host variable initialization moved outside the if statement so that it is used for both HELO and EHLO messages. And also it is cached, because I think its value will be the same during a series of successive calls to smtp_mail() (e.g. when sending notifications to subscribers).

Franz 2013-03-16 11:10:27

Ah, nice. Can you take care of that, John?

JohnLewis 2013-03-16 20:15:43

Will do. Probably tomorrow.

quy 2013-10-08 00:38:14

Commit 5fe6590 to fluxbb master

#710: Change $smtp_host to $local_host for HELO and cache $local_host. Thanks yoorick.