Current Path : /web/htdocs/www.entinoprofit.org/home/admin/
Upload File :
Current File : /web/htdocs/www.entinoprofit.org/home/admin/check.php

<?php
// phpinfo();

// constants
define("THUNDERPLUNGER_GUID", "{bfec0750-aa6f-11db-abbd-0800200c9a66}");

// note: the following 2 defines MUST refer to VALID domain and email as
// many servers check this and will reject us if they are not found
define("DOMAIN_TO_USE_FOR_SMTP", "out.alice.it");
define("EMAIL_TO_USE_FOR_SMTP", "webmaster@rivs.it");

define("EMAIL_UNSURE", "404");
define("EMAIL_GOOD", "200");
define("EMAIL_BAD", "400");
define("ERROR", "500");
define("SMTP_CONNECTION_TIMEOUT", 5);
define("SMTP_READ_TIMEOUT", 15);
define("SMTP_CONNECT_OK", "220");
define("SMTP_GENERIC_OK", "250");
define("EMAIL_REGEX", "/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/");
define("SMTP_PORT", 25);

// get the request query bits
if (strpos($_SERVER["REQUEST_URI"], "?")) {
  $QueryString = explode("?", $_SERVER["REQUEST_URI"]);
  $QueryArray = explode("&", $QueryString[1]);
  foreach ($QueryArray as $QueryItem) {
    $QuerySegment = explode("=", $QueryItem, 2);
    $_GET[$QuerySegment[0]] = urldecode($QuerySegment[1]);
  }
}

// get input parameters
$DEBUG_ENABLED = $_GET["test"];
$EMAIL_ADDRESS = $_GET["emailAddress"];
$THUNDERPLUNGER_ID = $_GET["accessKey"];

$timerStart;

// check that we are being invoked via the thunderplunger addon
if($THUNDERPLUNGER_ID != THUNDERPLUNGER_GUID)
{
  // we ignore this if we are in test mode
  if($DEBUG_ENABLED != "")
  {
    debugOut("No access key provided - ignored");
  }
  else
  {
    // otherwise, it is an error
    header($_SERVER['SERVER_PROTOCOL'] . " " . ERROR . " Missing or incorrect access key");
    header("Status: " . ERROR . " Missing or incorrect access key", true);
    return;
  }
}

// invoke the email check using the input email address
$checkResult = checkEmail($EMAIL_ADDRESS);

// if we are debugging, output our final conclusion
if($DEBUG_ENABLED != "")
{
  if(strcmp($checkResult->GetFirst(), EMAIL_GOOD) == 0)
  {
    debugOut("good");
  }
  else
  {
    if(strcmp($checkResult->GetFirst(), EMAIL_BAD) == 0)
    {
      debugOut("bad");
    }
    else
    {
      debugOut("unsure");
    }
  }

  debugOut($checkResult->GetSecond());
}

// check for leading garbage
$message = ltrim($checkResult->GetSecond(), " ~!@#$%^&*()_+=`';:=-[]{}|\<>.,?/\n");

// only take the first line of a multi-line response
$message = strtok($message, "\n");

debugOut("Message is $message");

// the following header sets the function's status code and message
header($_SERVER['SERVER_PROTOCOL'] . " " . $checkResult->GetFirst() . " " . $message, true, $checkResult->GetFirst());
header("Status: " . $checkResult->GetFirst() . " " . $message, true);

// end of mainline code
return;

// support windows platform (from http://www.php.net/manual/en/function.getmxrr.php#69869)
// which lacks an implementation of the getmxrr() function
if(!function_exists('getmxrr'))
{
  function getmxrr($hostname, &$mxhosts, &$mxweight)
  {
    if(!is_array($mxhosts))
    {
      $mxhosts = array();
    }

    if(!empty($hostname))
    {
      $output = "";
      @exec ("nslookup.exe -type=MX $hostname.", $output);
      $imx=-1;

      foreach($output as $line)
      {
        $imx++;
        $parts = "";
        if(preg_match("/^$hostname\tMX preference = ([0-9]+), mail exchanger = (.*)$/", $line, $parts))
        {
          $mxweight[$imx] = $parts[1];
          $mxhosts[$imx] = $parts[2];
        }
      }

      return($imx!=-1);
    }

    return false;
  }
}

function startTimer()
{
  global $DEBUG_ENABLED;
  if($DEBUG_ENABLED == "")
  {
    return;
  }

  global $timerStart;
  $timerStart = time();
}

function endTimer($message)
{
  global $DEBUG_ENABLED;
  if($DEBUG_ENABLED == "")
  {
    return;
  }

  global $timerStart;
  $totalTime = time() - $timerStart;
  debugOut($message . ". Time = $totalTime seconds");
}

// outputs a message if we are debugging, otherwise a no-op
function debugOut($message)
{
  global $DEBUG_ENABLED;

  if($DEBUG_ENABLED != "")
  {
    echo "<BR>" . $message;
  }
}

// the first 2 bytes are the result code, anything that follows is a
// status message. returns an instance of class Pair (see below) where
// the first item is the result code and the second is the status
// message
function readSmtpResult($sock)
{
  $result = "";

  startTimer();

  $result = fgetc($sock);
  $result .= fgetc($sock);
  $result .= fgetc($sock);

  endTimer("SMTP result: $result");

  $smtpResult = new Pair;
  $smtpResult->SetFirst($result);

  $result = "";

  // read everything in the socket's buffer so that we get the status
  // message and the buffer is clear for the next command
  startTimer();

//while(false !== ($char = fgetc($sock)))
//{
//  $result .= $char;
//}

  while(true)
  {
    $metadata = stream_get_meta_data($sock);
    if($metadata["unread_bytes"] == 0)
    {
      break;
    }

    $char = fgetc($sock);
    $result .= $char;
  }

  endTimer("Result message: $result");
  $smtpResult->SetSecond($result);
  return $smtpResult;
}

function sendSocket($sock, $data)
{
  startTimer();
  fwrite($sock, $data);
  endTimer("Finished socket send");
}

// interact with a mail exchange server for the domain of the email address
function doSmtp($domain, $email)
{
  // check that the domain actually exists. if it does NOT, this is a bogus email address
  $ip = gethostbyname($domain);

  // if debugging, show what we are doing
  $host = gethostbyname($domain);
  debugOut("Contacting $domain at $ip");

  // open a socket to the mail exchange server
  $sock = fsockopen($domain, SMTP_PORT, $errno, $errstr, SMTP_CONNECTION_TIMEOUT);

  // no need to go further if it fails
  if(!$sock)
  {
    return new Pair(ERROR, "$errno : $errstr");
  }

  // we can't wait forever
  stream_set_timeout($sock, SMTP_READ_TIMEOUT);

  // check that the SMTP server accepted our connection
  $result = readSmtpResult($sock);

  // if not, we cannot be sure of anything
  if(strcmp($result->GetFirst(), SMTP_CONNECT_OK) != 0)
  {
    debugOut("Connect failed");
    $result->SetFirst(EMAIL_UNSURE);
    fclose($sock);
    return $result;
  }

  // id ourselves to the SMTP server
  sendSocket($sock, sprintf("HELO %s\r\n", DOMAIN_TO_USE_FOR_SMTP));

  // check that the SMTP server accepted our id
  $result = readSmtpResult($sock);

  // if not, we cannot be sure of anything
  if(strcmp($result->GetFirst(), SMTP_GENERIC_OK) != 0)
  {
    debugOut("HELO failed");
    $result->SetFirst(EMAIL_UNSURE);
    fclose($sock);
    return $result;
  }

  // start a new email from us
  sendSocket($sock, sprintf("MAIL FROM: <%s>\r\n", EMAIL_TO_USE_FOR_SMTP));

  // check that the SMTP server accepted the email start
  $result = readSmtpResult($sock);

  // if not, we cannot be sure of anything
  if(strcmp($result->GetFirst(), SMTP_GENERIC_OK) != 0)
  {
    debugOut("MAIL FROM failed");
    $result->SetFirst(EMAIL_UNSURE);
    fclose($sock);
    return $result;
  }

  // we finally come to the crux of the matter. tell the SMTP server
  // that we want to deliver the email to the address that was input
  sendSocket($sock, sprintf("RCPT TO: <%s>\r\n", $email));

  // check that the SMTP server accepted the recipient address
  $result = readSmtpResult($sock);

  // some servers employ a catch-all so that they initially accept
  // an email to ANY recipient (and bounce them later). so a success
  // here does not detect that condition. we may report a GOOD email
  // address when it is not - but better safe than sorry. however,
  // a failure here does indicate that the recipient is not known. so
  // we can safely conclude that an address is BAD
  if(strcmp($result->GetFirst(), SMTP_GENERIC_OK) != 0)
  {
    debugOut("RCPT TO failed");
    $result->SetFirst(EMAIL_BAD);
    fclose($sock);
    return $result;
  }

  // if we get here, we conclude that the email address is GOOD. so
  // quit the conversation with the SMTP server. no email is actually
  // sent
  sendSocket($sock, "QUIT");
  fclose($sock);

  // all done
  debugOut("All looks good");
  return new Pair(EMAIL_GOOD, "Email OK");
}

function checkEmail($email)
{
  // checks proper email address syntax
  if(!preg_match(EMAIL_REGEX, $email))
  {
    return new Pair(EMAIL_BAD, "Does not conform to proper email address format");
  }

  // gets domain name
  list($username, $domain) = split('@', $email);

  // checks for if MX records in the DNS
  $mxhosts = array();
  startTimer();
  $getmxrrResult = getmxrr($domain, $mxhosts);
  endTimer("Got MX results");
  if(!$getmxrrResult)
  {
    debugOut("No mail exchange servers found. Using domain");

    // check that the domain actually exists. we have to do a little
    // odd stuff here because gethostbyname() and gethostbynamel() do
    // not behave as documented when a host name does not resolve
    $ip = gethostbyname($domain);
    debugOut("IP is $ip");

    $host = gethostbyaddr($ip);
    debugOut("Host is $host");

    if(false == strpos($host, $domain))
    {
      debugOut("Domain $domain not found");
      return new Pair(EMAIL_BAD, "Domain not found");
    }

    return doSmtp($domain, $email);
  }

  $result = "";

  // contact each of the mail exchange servers until we get a definitive
  // GOOD or BAD result
  foreach ($mxhosts as $host)
  {
    $result = doSmtp($host, $email);
    if((strcmp($result->GetFirst(), EMAIL_GOOD) == 0) || (strcmp($result->GetFirst(), EMAIL_BAD) == 0))
    {
      return $result;
    }
  }

  // if we get here, the result should be UNSURE or an ERROR
  return $result;
}

class Pair
{
  var $item1;
  var $item2;

  function Pair($itemA = NULL, $itemB = null)
  {
    $this->item1 = $itemA;
    $this->item2 = $itemB;
  }

  function GetFirst()
  {
    return $this->item1;
  }

  function GetSecond()
  {
    return $this->item2;
  }

  function SetFirst($data)
  {
    $this->item1 = $data;
  }

  function SetSecond($data)
  {
    $this->item2 = $data;
  }
}
?>