%PDF- %PDF-
| Direktori : /www/varak.net/mail2.varak.net_old/libraries/afterlogic/common/net/protocols/ |
| Current File : //www/varak.net/mail2.varak.net_old/libraries/afterlogic/common/net/protocols/sieve.php |
<?php
/*
* Copyright 2004-2014, AfterLogic Corp.
* Licensed under AGPLv3 license or AfterLogic license
* if commercial version of the product was purchased.
* See the LICENSE file for a full license statement.
*/
CApi::Inc('common.net.abstract');
/**
* @package Api
* @subpackage Net
*/
class CApiSieveProtocol extends CApiNetAbstract
{
/**
* @var array
*/
protected $aData;
public function __construct($sHost, $iPort, $bUseSsl = false, $iConnectTimeOut = null, $iSocketTimeOut = null)
{
parent::__construct($sHost, $iPort, $bUseSsl, $iConnectTimeOut, $iSocketTimeOut);
$this->aData = array();
}
/**
* @return bool
*/
public function Connect()
{
$sLine = '';
$bResult = false;
if (parent::Connect())
{
$sLine = $this->GetNextLine();
$aTokens = $this->parseLine($sLine);
if ($aTokens && isset($aTokens[0], $aTokens[1]) && 'IMPLEMENTATION' === $aTokens[0])
{
while (true)
{
if (false === $sLine || !isset($aTokens[0]) ||
in_array(substr($sLine, 0, 2), array('OK', 'NO')))
{
break;
}
$sLine = trim($sLine);
if (in_array($aTokens[0], array('IMPLEMENTATION', 'VERSION')))
{
$this->aData[$aTokens[0]] = $aTokens[1];
}
else if ('STARTTLS' === $aTokens[0])
{
$this->aData['STARTTLS'] = true;
}
else if (isset($aTokens[1]) && in_array($aTokens[0], array('SIEVE', 'SASL')))
{
$this->aData['TYPE'] = 'SASL' === $aTokens[0] ? 'AUTH' : 'MODULES';
$this->aData[$this->aData['TYPE']] = explode(' ', $aTokens[1]);
}
else
{
$this->aData['UNDEFINED'] = isset($this->aData['UNDEFINED'])
? $this->aData['UNDEFINED'] : array();
$this->aData['UNDEFINED'][] = $sLine;
}
$sLine = $this->GetNextLine();
$aTokens = $this->parseLine($sLine);
}
}
}
if ('OK' === substr($sLine, 0, 2))
{
$bResult = true;
}
if (CApi::GetConf('labs.sieve.use-starttls', false) && $bResult && isset($this->aData['STARTTLS']) && $this->aData['STARTTLS'])
{
$rConnect = $this->GetConnectResource();
if (is_resource($rConnect) && function_exists('stream_socket_enable_crypto'))
{
if ($this->SendLine('STARTTLS') && $this->CheckResponse($this->GetResponse()))
{
@stream_socket_enable_crypto($rConnect, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
$this->CheckResponse($this->GetResponse());
}
}
}
return $bResult;
}
/**
* @param string $sLogin
* @param string $sPassword
* @param string $sLoginAuthKey = ''
* @return bool
*/
public function Login($sLogin, $sPassword, $sLoginAuthKey = '')
{
$bResult = false;
if (isset($this->aData['AUTH']))
{
if (in_array('PLAIN', $this->aData['AUTH']))
{
$sAuth = base64_encode($sLoginAuthKey."\0".$sLogin."\0".$sPassword);
$this->SendLine('AUTHENTICATE "PLAIN" {'.strlen($sAuth).'+}');
$this->SendLine($sAuth);
$bResult = $this->CheckResponse($this->GetResponse());
}
else if (in_array('LOGIN', $this->aData['AUTH']))
{
$sLogin = base64_decode($sLogin);
$sPassword = base64_decode($sPassword);
$this->SendLine('AUTHENTICATE "LOGIN"');
$this->SendLine('{'.strlen($sLogin).'+}');
$this->SendLine($sLogin);
$this->SendLine('{'.strlen($sPassword).'+}');
$this->SendLine($sPassword);
$bResult = $this->CheckResponse($this->GetResponse());
}
}
return $bResult;
}
/**
* @return bool
*/
public function IsConnected()
{
return parent::IsConnected();
}
/**
* @param string $sLogin
* @param string $sPassword
* @return bool
*/
public function ConnectAndLogin($sLogin, $sPassword)
{
return $this->Connect() && $this->Login($sLogin, $sPassword);
}
/**
* @return bool
*/
public function Disconnect()
{
return parent::Disconnect();
}
/**
* @return bool
*/
public function Logout()
{
$this->SendLine('LOGOUT');
return $this->CheckResponse($this->GetResponse());
}
/**
* @return bool
*/
public function LogoutAndDisconnect()
{
return $this->Logout() && $this->Disconnect();
}
/**
* @return bool
*/
public function Capability()
{
$this->SendLine('CAPABILITY');
$aResponse = $this->GetResponse();
if ($this->CheckResponse($aResponse))
{
array_pop($aResponse);
$aCapa = array();
foreach ($aResponse as $sLine)
{
$aLine = $this->parseLine($sLine);
if (isset($aLine[0]))
{
$aCapa[$aLine[0]] = isset($aLine[1]) ? $aLine[1] : true;
}
}
return $aCapa;
}
return false;
}
/**
* @return array | bool
*/
public function ListScripts()
{
$this->SendLine('LISTSCRIPTS');
$aResponse = $this->GetResponse();
if ($this->CheckResponse($aResponse))
{
array_pop($aResponse);
$aList = array();
foreach ($aResponse as $sLine)
{
$aParsed = $this->parseLine($sLine);
if (!empty($aParsed[0]))
{
$aList[$aParsed[0]] = ('ACTIVE' === substr($sLine, -6));
}
}
return $aList;
}
return false;
}
/**
* @param string $sScriptName
* @return string | bool
*/
public function GetScript($sScriptName)
{
$this->SendLine('GETSCRIPT "'.$sScriptName.'"');
$aResponse = $this->GetResponse();
if ($this->CheckResponse($aResponse))
{
if ('{' === $aResponse[0]{0})
{
array_shift($aResponse);
}
array_pop($aResponse);
return implode("\n", $aResponse);
}
return false;
}
/**
* @param string $sScriptName
* @return string | bool
*/
public function GetScriptIfActive($sScriptName)
{
return ($this->IsActiveScript($sScriptName)) ? $this->GetScript($sScriptName) : false;
}
/**
* @param string $sScriptName
* @return bool
*/
public function IsActiveScript($sScriptName)
{
$aList = $this->ListScripts();
if (is_array($aList) && 0 < $aList)
{
foreach ($aList as $sName => $bIsActive)
{
if ($bIsActive && $sScriptName === $sName)
{
return true;
}
else if ($bIsActive)
{
break;
}
}
}
return false;
}
/**
* @return bool
*/
public function Noop()
{
$this->SendLine('NOOP');
return $this->CheckResponse($this->GetResponse());
}
/**
* @param string $sScriptName
* @param string $sScriptSource
* @return bool
*/
public function SendScript($sScriptName, $sScriptSource)
{
$sScriptSource = stripslashes($sScriptSource);
$this->SendLine('PUTSCRIPT "'.$sScriptName.'" {'.strlen($sScriptSource).'+}');
$this->SendLine($sScriptSource);
return $this->CheckResponse($this->GetResponse());
}
/**
* @param string $sScriptSource
* @return bool
*/
public function CheckScript($sScriptSource)
{
$sScriptSource = stripslashes($sScriptSource);
$this->SendLine('CHECKSCRIPT {'.strlen($sScriptSource).'+}');
$this->SendLine($sScriptSource);
return $this->CheckResponse($this->GetResponse());
}
/**
* @return bool
*/
public function SetActiveScript($sScriptName)
{
$this->SendLine('SETACTIVE "'.$sScriptName.'"');
return $this->CheckResponse($this->GetResponse());
}
/**
* @return bool
*/
public function DeleteScript($sScriptName)
{
$this->SendLine('DELETESCRIPT "'.$sScriptName.'"');
return $this->CheckResponse($this->GetResponse());
}
/**
* @param string $sCmd
* @return bool
*/
public function SendLine($sCmd)
{
return $this->WriteLine($sCmd);
}
/**
* @return string
*/
public function GetNextLine()
{
$sLine = $this->ReadLine();
return $sLine;
}
/**
* @return bool
*/
public function GetResponse()
{
$aLines = array();
do
{
$sLine = $this->GetNextLine();
if (false === $sLine)
{
break;
}
else if (in_array(substr($sLine, 0, 2), array('OK', 'NO')))
{
$aLines[] = trim($sLine);
break;
}
else
{
$aLines[] = trim($sLine);
}
}
while (true);
return $this->CheckResponse($aLines) ? $aLines : false;
}
/**
* @return bool
*/
public function CheckResponse($aResponse)
{
return is_array($aResponse) && 0 < count($aResponse) &&
'OK' === substr($aResponse[count($aResponse) - 1], 0, 2);
}
/**
* @param string $sLine
* @return array | false
*/
protected function parseLine($sLine)
{
if (false === $sLine || null === $sLine)
{
return false;
}
$iStart = -1;
$iIndex = 0;
$aResult = false;
for ($iPos = 0; $iPos < strlen($sLine); $iPos++)
{
if ('"' === $sLine[$iPos] && '\\' !== $sLine[$iPos])
{
if (-1 === $iStart)
{
$iStart = $iPos;
}
else
{
$aResult = is_array($aResult) ? $aResult : array();
$aResult[$iIndex++] = substr($sLine, $iStart + 1, $iPos - $iStart - 1);
$iStart = -1;
}
}
}
return $aResult;
}
}