[aur-dev] [PATCH] validate email and fully check existence of it

Ike Devolder ike.devolder at gmail.com
Tue Mar 20 07:23:15 EDT 2012


2012/3/20 Florian Pritz <bluewind at xinu.at>

> On 20.03.2012 10:36, BlackEagle wrote:
> > - check if the format is valid
> > - go and connect to the smtp server of the given domain and verify if
> >   the given email exists there
>
> Good idea, but I've seen mail servers accepting all recipients during
> the SMTP session, but later sending a DSN because the user didn't exist.
> That means we should still implement verification emails. Having this
> check is still good though.
>
> > ---
> >  web/lib/aur.inc.php |   75
> ++++++++++++++++++++++++++++++++++++++++++++++++++-
> >  1 files changed, 74 insertions(+), 1 deletions(-)
> >
> > diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php
> > index c662b80..3fc0a14 100644
> > --- a/web/lib/aur.inc.php
> > +++ b/web/lib/aur.inc.php
> > @@ -80,7 +80,80 @@ function check_sid($dbh=NULL) {
> >  # verify that an email address looks like it is legitimate
> >  #
> >  function valid_email($addy) {
> > -     return (filter_var($addy, FILTER_VALIDATE_EMAIL) !== false);
> > +    // check against RFC 3696
> > +    if(filter_var($addy, FILTER_VALIDATE_EMAIL) === false) {
> > +        return false;
> > +    }
> > +
> > +    // check dns for mx, a, aaaa records
> > +    list($local, $domain) = explode('@', $addy);
> > +    if(! (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A') ||
> checkdnsrr($domain, 'AAAA'))) {
>
> Please display an error message if this fails.
>
> > +        return false;
> > +    }
> > +
> > +    // get mx records and check full email address
> > +    $mxlist = array();
> > +    $mxweight = array();
> > +    getmxrr($domain, $mxlist, $mxweight);
>
> http://php.net/getmxrr#refsect1-function.getmxrr-notes states:
> "This function should not be used for the purposes of address
> verification. Only the mailexchangers found in DNS are returned ..."
>
> > +    $mx = array_combine($mxweight, $mxlist);
> > +    ksort($mx);
> > +
> > +    //smtp_test_email($addy, current($mx));
> > +    foreach($mx as $prio => $mxsrv) {
> > +        if(smtp_test_email($addy, $mxsrv) === true) {
> > +            return true;
> > +        }
> > +    }
>
> Since this will eventually return false negatives, please display all
> SMTP sessions if you get here. This will help users understand what went
> wrong so they can fix it more easily.
>
> > +
> > +    return false;
> > +}
> > +
> > +# verify that an email address exists on the smtp server
> > +#
> > +function smtp_test_email($addy, $mxsrv) {
> > +    if(($smtp = fsockopen($mxsrv, 25)) === false) {
> > +        return false;
> > +    }
> > +
> > +    if(intval(preg_replace('/^\([0-9]{3}\).*/', '\1', fgets($smtp)))
> !== 220) {
> > +        smtp_close($smtp);
> > +        return false;
> > +    }
> > +
> > +    fwrite($smtp, "HELO $mxsrv\r\n");
>
> HELO should send the client name, not the server name.
>
> > +    if(intval(preg_replace('/^\([0-9]{3}\).*/', '\1', fgets($smtp)))
> !== 250) {
> > +        smtp_close($smtp);
> > +        return false;
> > +    }
> > +
> > +    fwrite($smtp, "MAIL FROM: <mailtest at archlinux.org>\r\n");
> > +    if(intval(preg_replace('/^\([0-9]{3}\).*/', '\1', fgets($smtp)))
> !== 250) {
> > +        smtp_close($smtp);
> > +        return false;
> > +    }
> > +
> > +    fwrite($smtp, "RCPT TO: <$addy>\r\n");
> > +    $code = intval(preg_replace('/^\([0-9]{3}\).*/', '\1',
> fgets($smtp)));
> > +    /**
> > +     * 250 = success
> > +     * 451 or 452 = address got greylisted but another error occured
>
> s/got/not/?
>

got


> > +     *              so assume ok
> > +     */
> > +    if($code !== 250 && $code !== 451 && $code !== 452) {
>
> I'm not sure if rejecting greylisted adresses is a good idea because
> that means the users have to resubmit the form after 5-30 minutes. You
> should ask them to confirm that their address is correct (typo catching)
> and then ignore all temporary errors (all 4xx codes). If you get a 5xx
> it's fine to abort.
>

the above does allow the greylisted accounts


>
> If you want to make sure the address really exists, you have to
> implement verification mails. Just checking return codes for RCPT TO is
> not enough.
>
> > +        smtp_close($smtp);
> > +        return false;
> > +    }
> > +
> > +    smtp_close($smtp);
> > +    return true;
> > +}
> > +
> > +# close smtp conneciton
> > +#
> > +function smtp_close(&$smtp) {
> > +    fwrite($smtp, "RSET\r\n");
> > +    fwrite($smtp, "QUIT\r\n");
> > +    fclose($smtp);
> >  }
> >
> >  # a new seed value for mt_srand()
>
>
> --
> Florian Pritz
>
>
then you should just drop this check and only do the mx, a, ... check for
the obvious ones

and then send the verification mail for full confirmation

-- 
Ike


More information about the aur-dev mailing list