Skip to content

Instantly share code, notes, and snippets.

@kimboslice99
Created January 2, 2025 06:34
Show Gist options
  • Save kimboslice99/47698f0d64cad3e699352e6e92c995a7 to your computer and use it in GitHub Desktop.
Save kimboslice99/47698f0d64cad3e699352e6e92c995a7 to your computer and use it in GitHub Desktop.
A php function to check if an email address is truly valid and does exist
<?php
function IsValidMailbox($address){
if(preg_match('/@([^\s]+)/i', $address, $matches)){
if(dns_get_mx($matches[1], $out)){
$timeout = 10; // Timeout for connection
$mailServer = $out[0];
// Open a plaintext connection to the mail server. Assuming port 25 outbound isnt blocked here
$connection = stream_socket_client(
"$mailServer:25",
$errno,
$errstr,
$timeout,
STREAM_CLIENT_CONNECT
);
if (!$connection) {
return "Failed to connect: $errstr ($errno)";
}
// Step 1: Wait for the 220 response from the server to confirm readiness
$response = fgets($connection, 512);
if (substr($response, 0, 3) != '220') {
fclose($connection);
return $response;
}
// Step 2: Send EHLO command to initiate communication
$response = sendCommand($connection, "EHLO localhost");
if (strpos($response, '250') === false) {
fclose($connection);
return "EHLO failed.";
}
// Step 3: Check if STARTTLS is supported
if (strpos($response, 'STARTTLS') !== false) {
// Step 4: Send STARTTLS command
$response = sendCommand($connection, "STARTTLS");
if (strpos($response, '220') === false) {
fclose($connection);
return "STARTTLS failed." . $response;
}
// Step 5: Upgrade the connection to secure (TLS)
stream_socket_enable_crypto($connection, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
// Step 6: Reissue EHLO after upgrading to TLS
$response = sendCommand($connection, "EHLO localhost");
if (strpos($response, '250') === false) {
fclose($connection);
return "EHLO after STARTTLS failed.";
}
} else {
fclose($connection);
return "STARTTLS not supported by the server." . $response;
}
$response = sendCommand($connection, "MAIL FROM:<[email protected]>");
if (strpos($response, '250') === false) {
fclose($connection);
return "MAIL FROM Failed.";
}
$commands = [
"RCPT TO:<$address>", // Email to verify
"QUIT"
];
$fullResponse = '';
foreach ($commands as $command) {
$response = sendCommand($connection, $command);
$fullResponse .= $response . "\n";
}
fclose($connection);
// Step 8: Check the response for RCPT TO command
if (strpos($fullResponse, '250') !== false) {
return "Email exists.";
} elseif (strpos($fullResponse, '550') !== false) {
return "Email does not exist.";
} else {
return "Unable to verify email.";
}
}
}
return false;
}
function sendCommand($connection, $command) {
fwrite($connection, $command . "\r\n");
$response = '';
while ($line = fgets($connection, 512)) {
$response .= $line;
// If the line doesn't end with a dash, it's the last line of the response
if (substr($line, 3, 1) != '-') {
break;
}
}
return $response;
}
var_dump(IsValidMailbox('[email protected]'));
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment