3

I have a PHP script on a Linux server that needs to determine whether an email address is real or fake.

I'm trying to use telnet for this, launched from an expect script, but it's not working.

The PHP script usage would be:

$retVal = shell_exec( "./atelnet.sh mailserver.net fake@example.com" ) ;

Any help would be appreciated, or a better approach altogether.

Thank you.

Here's what I have so far:

#!/usr/bin/expect
#
# name: atelnet.sh
# usage from php: 
# $retVal = shell_exec( "./atelnet.sh mailserver.net fake@example.com" ) ;
#
# if goes wrong, the script will timeout in 20 seconds
set timeout 20

# first argument assigned to the variable "server"
set server [lindex $argv 0]

# second argument assigned to the variable "emailaddress"
set emailaddress [lindex $argv 1]

# spawn telnet and connect to variable "server" on port 25
spawn telnet $server 25

# script expects "220 ..." telnet from server, telnet login ok response
# actual response looks like: 
# "220 mx.server.com ESMTP ni10si2925797obc.73 - gsmtp"
# or
# "220-host.server.com ESMTP Fri, 22 Mar 2013 01:48:03 -0000"
expect "220"

# script sends initial handshake greeting
send "HELO"

# script expects "250 ..." telnet from server, at-your-service ok response
# actual response looks like: 
# "250 mx.server.com at your service"
# or
# "250 host.server.com Hello host.server.com [111.222.333.444]"
expect "250"

# script sends from: email address (any address is fine)
send "mail from:<a@b.com>"

# script expects "250 ..." telnet from server, ok acknowledgement of from:email
# actual response looks like: 
# "250 2.1.0 OK v16si1294229qct.125 - gsmtp"
# or
# "250 OK"
expect "250"

# script sends query to the email address being tested
# PHP string cat syntax doesn't work !!!
# HOW ???
send "rcpt to:<" . $emailaddress . ">"

# script expects one of these:
# fake: "550-5.1.1 The email account that you tried to reach does not exist."
# or
# true: "250 Accepted"

# log server's response to file. HOW ???

EDIT:

I'm adding below my PHP socket code, which doesn't seem to work:

$smtp_server = fsockopen( $mx_hostname, 25, $errno, $errstr, 30 ) ;
$ret1 = fwrite( $smtp_server, "helo hi\r\n" ) ;
$ret2 = fwrite( $smtp_server, "mail from: <a@b.org>\r\n" ) ;
$ret3 = fwrite( $smtp_server, "rcpt to: <" . $unk_email_address. ">\r\n" ) ;

Any ideas on this code would be welcomed as well.

Thank you.

RadUma
  • 63
  • 1
  • 1
  • 6
  • Check out this answer here: http://stackoverflow.com/questions/565504/how-to-check-if-an-email-address-exists-without-sending-an-email?answertab=votes#tab-top – Gábor Nádai Mar 22 '13 at 23:58
  • @GáborNádai, thanks for that link. Basically there's no guarantee that you can determine whether an email address is real or fake, because many email hosts block attempts to discover their users, but you can weed out a lot of fake email addresses if you try. – RadUma Mar 23 '13 at 00:41

3 Answers3

1

I can see the intended usage but I would say that it is a little bit of an overkill to actually connect and initiate a handshake with the recipient mail server. Especially since there are still no guarantees that it means the user exists.

You should check for an MX record before this stage, see getmxrr
Assuming you already checked validated it as a valid e-mail string I would say combining that with the additional MX lookup is enough.

If you still want to do it I would implement it using PHP sockets instead of telnet. Maybe even using the expect extension since you already started that path.

Other ideas could be to have Facebook and Google oauth login on your website if it is related to higher quality user sign up

baloo
  • 7,635
  • 4
  • 27
  • 35
  • I'm already checking MX records. The above script executes only if at least one MX record exists. But thanks for PHP's getmxrr(), I was checking MX records with dig. I also tried PHP sockets for the same functionality as the above script, but somehow that didn't work. – RadUma Mar 23 '13 at 00:28
  • All I want to say is, don't overdo it :) This is definitely not the biggest problem of reaching the end user – baloo Mar 23 '13 at 00:33
  • Users are signing up using fake email addresses. To reduce signup friction we allow them on the site without authenticating them via a click on an emailed link. This is causing problems, but we still want to minimize friction for new signups. Any ideas? – RadUma Mar 23 '13 at 00:56
  • Providing a Facebook signup doesn't have to be that complicated, depending on your target group that would be the least friction for signing up imo. And you would be sure that the e-mail is correct. – baloo Mar 23 '13 at 00:59
  • I want to keep the signup process and data in-house. Any ideas as to why my PHP sockets code isn't working (please see my edit above)? – RadUma Mar 23 '13 at 01:18
  • I got the socket code working. The problem now is that MX hosts tend to greylist your server if you make too many inquiries about their users, so this approach may not work after all. – RadUma Mar 23 '13 at 19:48
0

There is no point trying to invent wheel.

Check for example: Zend_Validate_EmailAddress

You can even validate hostname and mx record

$validator = new Zend_Validate_EmailAddress(
    array(
        'allow' => Zend_Validate_Hostname::ALLOW_DNS,
        'mx'    => true
    )
);

and by validating existing domain and email address format I would say it should be enough.

baloo
  • 7,635
  • 4
  • 27
  • 35
Zdenek Machek
  • 1,758
  • 1
  • 20
  • 30
  • I'm already validating the email address. The above script tries to determine whether an already validated email address actually exists as a real user on the given email host. From my reading of Zend, it only does email address validation, and can also validate the MX record of the email host, but cannot determine if the email address is real or fake. – RadUma Mar 23 '13 at 00:34
  • There is only one way how to find out if email is real, send activation email and ask user to click activation link. Even this is not 100%, because by email nature, you have no guarantee that sent email will be delivered. As somebody already mentioned, OAuth or OpenId would be better solution. – Zdenek Machek Mar 23 '13 at 23:18
  • Will probably go with authetication email and clickable link. – RadUma Mar 25 '13 at 05:23
0

You can use PHP Filters to validate an E-mail:

http://php.net/manual/en/filter.filters.validate.php

$email_a = 'user@example.com';


if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) {
    echo "This (email_a) email address is considered valid.";
}
Daryl Gill
  • 5,464
  • 9
  • 36
  • 69
  • I'm already validating the email address. The above script tries to determine whether an already validated email address actually exists as a real user on the given email host. – RadUma Mar 23 '13 at 00:30