sdyates has asked for the wisdom of the Perl Monks concerning the following question:

I say a few threads and put together some code as you can see below. I want to be able to determine if an address is valid: both the domain and account name. I don't really care if one or the other is valid, if either is invalid, then I consider the address to be invalid.

The code below is not very good, dispite several hours of work. eee@eee.com is ok. It does fail on addresses where there is no valid domain, but my code does not determine if the user account is valid. Before I continue to rack my brains, can I actually determine if a given email address is valid? Can Email::Valid or any other module actually call the mx daemon at ee.com to see if the given account, eee, is valid?

I continue to look, but am beginning to realise the best way is to talk directly to the smtp port directly, but I fear the code could develope into a nightmare...I sense this is really easy and I am just missing the point. Can someone hit me with a 2x4?

Please advise,

Simon

if($EmailAddress) { eval { if (my $addr = Email::Valid->address( -address => $EmailAd +dress, function start() { document.forms[0].elements[0].focus(); } </SCRIPT> </HEAD> <body bgcolor='ffffcc' onLoad='start()'> "; generate_form(); my $EmailAddress = $cgi->param('EmailAddress'); if($EmailAddress) { eval { if (my $addr = Email::Valid->address( -address => $EmailAd +dress, -mxcheck => 1, -fudge => 1 )) { print "$addr OK\n"; } else { print "$addr failed $Email::Valid::Details check.\n"; } }; warn "an error was encountered: $@" if $@; } print end_html();

Replies are listed 'Best First'.
Re: Determining a valid address
by Juerd (Abbot) on Apr 02, 2002 at 22:00 UTC

    This is a FAQ, answered in perlfaq9:

    How do I check a valid mail address?

    You can't, at least, not in real time. Bummer, eh?

    Without sending mail to the address and seeing whether there's a human on the other hand to answer you, you can- not determine whether a mail address is valid. Even if you apply the mail header standard, you can have problems, because there are deliverable addresses that aren't RFC-822 (the mail header standard) compliant, and addresses that aren't deliverable which are compliant.

    Many are tempted to try to eliminate many frequently- invalid mail addresses with a simple regex, such as "/^[\w.-]+\@(?:[\w-]+\.)+\w+$/". It's a very bad idea. However, this also throws out many valid ones, and says nothing about potential deliverability, so it is not sug- gested. Instead, see http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/ckaddr.gz, which actually checks against the full RFC spec (except for nested comments), looks for addresses you may not wish to accept mail to (say, Bill Clinton or your postmaster), and then makes sure that the hostname given can be looked up in the DNS MX records. It's not fast, but it works for what it tries to do.

    Our best advice for verifying a person's mail address is to have them enter their address twice, just as you nor- mally do to change a password. This usually weeds out typos. If both versions match, send mail to that address with a personal message that looks somewhat like:

    Dear someuser@host.com, Please confirm the mail address you gave us Wed May 6 09:38:41 MDT 1998 by replying to this message. Include the string "Rumpelstiltskin" in that reply, but spelled in reverse; that is, start with "Nik...". Once this is done, your confirmed address will be entered into our records.

    If you get the message back and they've followed your directions, you can be reasonably assured that it's real.

    A related strategy that's less open to forgery is to give them a PIN (personal ID number). Record the address and PIN (best that it be a random one) for later processing. In the mail you send, ask them to include the PIN in their reply. But if it bounces, or the message is included via a ``vacation'' script, it'll be there anyway. So it's best to ask them to mail back a slight alteration of the PIN, such as with the characters reversed, one added or subtracted to each digit, etc.

    U28geW91IGNhbiBhbGwgcm90MTMgY
    W5kIHBhY2soKS4gQnV0IGRvIHlvdS
    ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
    geW91IHNlZSBpdD8gIC0tIEp1ZXJk
    

      I did a little more homework with the assistance given above and some more grinding of teeth.

      I am now using use Mail::CheckUser qw(check_email last_check) which claims to be able to check the user mailbox:

      "This Perl module provides routines for checking validity of email address.

      It makes several checks:

      1 It checks the syntax of an email address.

      2 It checks if there any MX records or A records for the domain part of the email address.

      3 It tries to connect to an email server directly via SMTP to check if mailbox is valid. Old versions of this module performed this check via the VRFY command. Now the module uses another check; it uses a combination of MAIL and RCPT commands which simulates sending an email. It can detect bad mailboxes in many cases. For example, hot­ mail.com mailboxes can be verified with the MAIL/RCPT check."

      Well, I give it bad addresses like 333@roxio.com and it passes. Trust me on this one, that is not a have email, even though it is vailid under RFC 822. THe script does take a while to check the addresses.

      Am I coding the script wrong? Am I missing something?

      use... bla bla just as above :) my $EmailAddress = $cgi->param('EmailAddress'); if($EmailAddress) { my $res = Mail::CheckUser::check_email($EmailAddress); if($res==1) { print "E-mail address $EmailAddress is OK\n"; } else { print "E-mail address $EmailAddress isn't valid: ", } }
Re: Determining a valid address
by gav^ (Curate) on Apr 02, 2002 at 21:51 UTC
    Mail::CheckUser claims to be able to do this, but the best way to ensure a valid email address is to send something to it. For example, I can enter 'postmaster@microsoft.com' which isn't my valid email address.

    gav^

Re: Determining a valid address
by blackflag (Novice) on Apr 02, 2002 at 21:59 UTC
    This will not work under various circumstances, but I believe that it generally will.
    I would try using the Net::Finger module. The documentation at that site is pretty straightforward, so you should have very little problems.
    This should work with sites that give the user an account. However, I do not think that it will work with a web-mail account like Yahoo! or Excite. This module queries the server for a user. The server you are using may not have the Net::Finger module. If it doesn't, I would just download the module and modify it for your use. I'd help you more, but I don't know the syntax for a Finger query.

    E-mail ( lied5@yahoo.com ) or /msg me if you need any more help
    Peace... BlackFlag