%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; } }