Skip to content

Instantly share code, notes, and snippets.

@gaffling
Created April 3, 2021 12:19
Show Gist options
  • Save gaffling/8c4b00480028d3134ec28d9912250918 to your computer and use it in GitHub Desktop.
Save gaffling/8c4b00480028d3134ec28d9912250918 to your computer and use it in GitHub Desktop.
[Mail Validation] Use SMTP to validate eMail Address #php #function #mailcheck
/* ------------------------------------------------------------------------------ */
/* [Mail Validation] Use SMTP to validate eMail Address #php #function #mailcheck */
/* ------------------------------------------------------------------------------ */
function doSMTPValidation($email, $probe_address='', $debug=false) {
$output = '';
if (!$probe_address) $probe_address = $_SERVER['SERVER_ADMIN'];
if (preg_match('/^([a-zA-Z0-9\._\+-]+)\@((\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,7}|[0-9]{1,3})(\]?))$/', $email, $matches)) {
$user = $matches[1];
$domain = $matches[2];
if (function_exists('checkdnsrr')) {
if (getmxrr($domain, $mxhosts, $mxweight)) {
for ($i=0;$i<count($mxhosts);$i++) {
$mxs[$mxhosts[$i]] = $mxweight[$i];
}
asort($mxs);
$mailers = array_keys($mxs);
} elseif (checkdnsrr($domain, 'A')) {
$mailers[0] = gethostbyname($domain);
} else {
$mailers=array();
}
$total = count($mailers);
if ($total > 0) {
for ($n=0; $n < $total; $n++) {
if ($debug) { $output .= 'Checking server '.$mailers[$n].'...'.PHP_EOL; }
$connect_timeout = 2;
$errno = 0;
$errstr = 0;
if (preg_match('/^([a-zA-Z0-9\._\+-]+)\@((\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,7}|[0-9]{1,3})(\]?))$/', $probe_address,$fakematches)) {
$probe_domain = str_replace('@', '',strstr($probe_address, '@'));
if ($sock = @fsockopen($mailers[$n], 25, $errno , $errstr, $connect_timeout)) {
$response = fgets($sock);
if ($debug) { $output .= 'Opening up socket to '.$mailers[$n].'... Success!'.PHP_EOL; }
stream_set_timeout($sock, 5);
$meta = stream_get_meta_data($sock);
if($debug) { $output .= $mailers[$n].' replied: '.$response.PHP_EOL; }
$cmds = array(
'HELO '.$probe_domain,
'MAIL FROM: <'.$probe_address.'>',
'RCPT TO: <'.$email.'>',
'QUIT',
);
if (!$meta['timed_out'] && !preg_match('/^2\d\d[ -]/', $response)) {
$code = trim(substr(trim($response),0,3));
if ($code=='421') {
$error = $response;
break;
} else {
if ($response=='' || $code=='') {
$code = '0';
}
$error = 'Error: '.$mailers[$n].' said: '.$response.PHP_EOL;
break;
}
break;
}
foreach ($cmds as $cmd) {
$before = microtime(true);
fputs($sock, $cmd."\r\n");
$response = fgets($sock, 4096);
$t = 1000*(microtime(true)-$before);
if ($debug) { $output .= $cmd.PHP_EOL.$response.'('.sprintf('%.2f', $t).' ms)'.PHP_EOL; }
if (!$meta['timed_out'] && preg_match('/^5\d\d[ -]/', $response)) {
$code = trim(substr(trim($response),0,3));
if ($code <> '552') {
$error = 'Unverified address: '.$mailers[$n].' said: '.$response;
break 2;
} else {
$error = $response;
break 2;
}
}
}
fclose($sock);
if ($debug) { $output .= 'Succesful communication with '.$mailers[$n].', no hard errors, assuming OK'.PHP_EOL; }
break;
} elseif ($n == $total-1) {
$error = 'None of the mailservers listed for '.$domain.' could be contacted';
$code = '0';
}
} else {
$error = 'The probe_address is not a valid mail.';
}
}
} elseif ($total <= 0) {
$error = 'No usable DNS records found for domain '.$domain;
}
}
} else {
$error = 'Address syntax not correct';
}
if ($debug) {
print nl2br(htmlentities($output));
}
if (!isset($code)) { $code = 'n.a.'; }
if (isset($error)) return array($error, $code); else return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment