function __ProcessCommand($command, $arg = '')
{
switch(mb_strtoupper($command))
{
case "HELO":
$this->Send('250', 'domain name should be qualified');
if(trim($arg) == '')
{
$this->host = $this->ip;
}
else
{
$this->host = $arg;
}
//500, 501, 504, 421
break;
case "SEND":
case "SOML":
case "SAML":
case "MAIL":
if(!preg_match('#FROM[ ]*:[ ]*(.+)#i', $arg, $arMatches))
{
$this->Send('501', 'Unrecognized parameter '.$arg);
}
elseif($this->arMsg["FROM"])
{
$this->Send('503', 'Sender already specified');
}
else
{
$email = $arMatches[1];
$email = CMailUtil::ExtractMailAddress($email);
if($email == '' || !check_email($email))
{
$this->Send('501', '<'.$email.'> Invalid Address');
}
else
{
$this->arMsg["FROM"] = $email;
$this->arMsg["TO"] = array();
$this->Send('250', '<'.$email.'> Sender ok');
}
}
//F: 552, 451, 452
//E: 500, 501, 421
break;
case "RCPT":
if(!preg_match('#TO[ ]*:[ ]*(.+)#i', $arg, $arMatches))
{
$this->Send('501', 'Unrecognized parameter '.$arg);
}
else
{
$email = $arMatches[1];
$email = CMailUtil::ExtractMailAddress($email);
if($email == '' || !check_email($email))
{
$this->Send('501', '<'.$email.'> Invalid Address');
}
elseif(false)
{
$this->Send('550', '<'.$email.'> User unknown');
}
elseif(!$this->CheckRelaying($email))
{
$this->Send('550', '<'.$email.'>... Relaying denied.');
}
elseif(!$this->arMsg["FROM"])
{
$this->Send('503', 'Sender is not specified');
}
else
{
$this->arMsg["TO"][] = $email;
$this->Send('250', '<'.$email.'> ok');
//S: 250, 251
//F: 550, 551, 552, 553, 450, 451, 452
//E: 500, 501, 503, 421
}
}
break;
case "DATA":
if(!$this->arMsg["FROM"] || !$this->arMsg["TO"] || count($this->arMsg["TO"]) == 0)
{
$this->Send('503');
}
else
{
$this->Send('354');
$this->__listenFunc = '__DataHandler';
}
// I: 354 -> data -> S: 250
// F: 552, 554, 451, 452
// F: 451, 554
// E: 500, 501, 503, 421
break;
case "RSET":
$this->Send('250', 'Resetting');
$this->arMsg = array('LOCAL_ID' => md5(uniqid()));
//E: 500, 501, 504, 421
break;
case "QUIT":
$this->Send('221');
$this->Disconnect();
//E: 500
break;
case "EHLO":
if(trim($arg) == '')
{
$this->host = $this->ip;
}
else
{
$this->host = $arg;
}
$this->Send('250-ehlo', '');
$this->Send('250-AUTH LOGIN PLAIN', '');
//$this->Send('250-SIZE', '');
$this->Send('250-HELP', '');
$this->Send('250', 'EHLO');
/*
250-mail.company2.tld is pleased to meet you
250-DSN
250-SIZE
250-STARTTLS
250-AUTH LOGIN PLAIN CRAM-MD5 DIGEST-MD5 GSSAPI MSN NTLM
250-ETRN
250-TURN
250-ATRN
250-NO-SOLICITING
250-HELP
250-PIPELINING
250 EHLO
*/
break;
case "AUTH":
if($this->authorized)
{
$this->Send('503', 'Already authorized');
}
elseif(count($this->arMsg) > 1)
{
$this->Send('503', 'Mail transaction is active');
}
elseif(!preg_match('#^([A-Z0-9-_]+)[ ]*(S*)$#i', $arg, $arMatches))
{
$this->Send('501', 'Unrecognized parameter '.$arg);
}
else
{
switch(mb_strtoupper($arMatches[1]))
{
case "LOGIN":
$this->Send('334', 'VXNlcm5hbWU6');
$this->__listenFunc = '__AuthLoginHandler';
$this->__login = false;
break;
case "PLAIN":
if($arMatches[2] && trim($arMatches[2]) != '')
{
$pwd = base64_decode($arMatches[2]);
$this->Authorize($pwd, $pwd);
}
else
{
$this->Send('334', '');
$this->__listenFunc = '__AuthPlainHandler';
}
break;
default:
$this->Send('504', 'Unrecognized authentication type.');
}
}
break;
case "NOOP":
$this->Send('250');
//E: 500, 421
break;
case "HELP":
// S: 211, 214
// E: 500, 501, 502, 504, 421
break;
case "EXPN":
//
// S: 250
// F: 550
// E: 500, 501, 502, 504, 421
break;
case "VRFY":
// S: 250, 251
// F: 550, 551, 553
// E: 500, 501, 502, 504, 421
break;
default:
$this->Send('500', $command.' command unrecognized');
}
return true;
}