| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 | 
							- <?php
 - 
 - /**
 -  *  Classes for managesieve operations (using PEAR::Net_Sieve)
 -  *
 -  * Copyright (C) 2008-2011, The Roundcube Dev Team
 -  * Copyright (C) 2011, Kolab Systems AG
 -  *
 -  * This program is free software: you can redistribute it and/or modify
 -  * it under the terms of the GNU General Public License as published by
 -  * the Free Software Foundation, either version 3 of the License, or
 -  * (at your option) any later version.
 -  *
 -  * This program is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 -  * GNU General Public License for more details.
 -  *
 -  * You should have received a copy of the GNU General Public License
 -  * along with this program. If not, see http://www.gnu.org/licenses/.
 -  */
 - 
 - // Managesieve Protocol: RFC5804
 - 
 - class rcube_sieve
 - {
 -     private $sieve;                 // Net_Sieve object
 -     private $error = false;         // error flag
 -     private $list = array();        // scripts list
 - 
 -     public $script;                 // rcube_sieve_script object
 -     public $current;                // name of currently loaded script
 -     private $exts;                  // array of supported extensions
 - 
 -     const ERROR_CONNECTION = 1;
 -     const ERROR_LOGIN      = 2;
 -     const ERROR_NOT_EXISTS = 3;    // script not exists
 -     const ERROR_INSTALL    = 4;    // script installation
 -     const ERROR_ACTIVATE   = 5;    // script activation
 -     const ERROR_DELETE     = 6;    // script deletion
 -     const ERROR_INTERNAL   = 7;    // internal error
 -     const ERROR_DEACTIVATE = 8;    // script activation
 -     const ERROR_OTHER      = 255;  // other/unknown error
 - 
 - 
 -     /**
 -      * Object constructor
 -      *
 -      * @param string  Username (for managesieve login)
 -      * @param string  Password (for managesieve login)
 -      * @param string  Managesieve server hostname/address
 -      * @param string  Managesieve server port number
 -      * @param string  Managesieve authentication method 
 -      * @param boolean Enable/disable TLS use
 -      * @param array   Disabled extensions
 -      * @param boolean Enable/disable debugging
 -      * @param string  Proxy authentication identifier
 -      * @param string  Proxy authentication password
 -      * @param array   List of options to pass to stream_context_create().
 -      */
 -     public function __construct($username, $password='', $host='localhost', $port=2000,
 -         $auth_type=null, $usetls=true, $disabled=array(), $debug=false,
 -         $auth_cid=null, $auth_pw=null, $options=array())
 -     {
 -         $this->sieve = new Net_Sieve();
 - 
 -         if ($debug) {
 -             $this->sieve->setDebug(true, array($this, 'debug_handler'));
 -         }
 - 
 -         $result = $this->sieve->connect($host, $port, $options, $usetls);
 - 
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_CONNECTION);
 -         }
 - 
 -         if (!empty($auth_cid)) {
 -             $authz    = $username;
 -             $username = $auth_cid;
 -         }
 -         if (!empty($auth_pw)) {
 -             $password = $auth_pw;
 -         }
 - 
 -         $result = $this->sieve->login($username, $password, $auth_type ? strtoupper($auth_type) : null, $authz);
 - 
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_LOGIN);
 -         }
 - 
 -         $this->exts = $this->get_extensions();
 - 
 -         // disable features by config
 -         if (!empty($disabled)) {
 -             // we're working on lower-cased names
 -             $disabled = array_map('strtolower', (array) $disabled);
 -             foreach ($disabled as $ext) {
 -                 if (($idx = array_search($ext, $this->exts)) !== false) {
 -                     unset($this->exts[$idx]);
 -                 }
 -             }
 -         }
 -     }
 - 
 -     public function __destruct() {
 -         $this->sieve->disconnect();
 -     }
 - 
 -     /**
 -      * Getter for error code
 -      */
 -     public function error()
 -     {
 -         return $this->error ?: false;
 -     }
 - 
 -     /**
 -      * Saves current script into server
 -      */
 -     public function save($name = null)
 -     {
 -         if (!$this->sieve) {
 -             return $this->_set_error(self::ERROR_INTERNAL);
 -         }
 - 
 -         if (!$this->script) {
 -             return $this->_set_error(self::ERROR_INTERNAL);
 -         }
 - 
 -         if (!$name) {
 -             $name = $this->current;
 -         }
 - 
 -         $script = $this->script->as_text();
 - 
 -         if (!$script) {
 -             $script = '/* empty script */';
 -         }
 - 
 -         $result = $this->sieve->installScript($name, $script);
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_INSTALL);
 -         }
 - 
 -         return true;
 -     }
 - 
 -     /**
 -      * Saves text script into server
 -      */
 -     public function save_script($name, $content = null)
 -     {
 -         if (!$this->sieve) {
 -             return $this->_set_error(self::ERROR_INTERNAL);
 -         }
 - 
 -         if (!$content) {
 -             $content = '/* empty script */';
 -         }
 - 
 -         $result = $this->sieve->installScript($name, $content);
 - 
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_INSTALL);
 -         }
 - 
 -         return true;
 -     }
 - 
 -     /**
 -      * Activates specified script
 -      */
 -     public function activate($name = null)
 -     {
 -         if (!$this->sieve) {
 -             return $this->_set_error(self::ERROR_INTERNAL);
 -         }
 - 
 -         if (!$name) {
 -             $name = $this->current;
 -         }
 - 
 -         $result = $this->sieve->setActive($name);
 - 
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_ACTIVATE);
 -         }
 - 
 -         return true;
 -     }
 - 
 -     /**
 -      * De-activates specified script
 -      */
 -     public function deactivate()
 -     {
 -         if (!$this->sieve) {
 -             return $this->_set_error(self::ERROR_INTERNAL);
 -         }
 - 
 -         $result = $this->sieve->setActive('');
 - 
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_DEACTIVATE);
 -         }
 - 
 -         return true;
 -     }
 - 
 -     /**
 -      * Removes specified script
 -      */
 -     public function remove($name = null)
 -     {
 -         if (!$this->sieve) {
 -             return $this->_set_error(self::ERROR_INTERNAL);
 -         }
 - 
 -         if (!$name) {
 -             $name = $this->current;
 -         }
 - 
 -         // script must be deactivated first
 -         if ($name == $this->sieve->getActive()) {
 -             $result = $this->sieve->setActive('');
 - 
 -             if (is_a($result, 'PEAR_Error')) {
 -                 return $this->_set_error(self::ERROR_DELETE);
 -             }
 -         }
 - 
 -         $result = $this->sieve->removeScript($name);
 - 
 -         if (is_a($result, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_DELETE);
 -         }
 - 
 -         if ($name == $this->current) {
 -             $this->current = null;
 -         }
 - 
 -         return true;
 -     }
 - 
 -     /**
 -      * Gets list of supported by server Sieve extensions
 -      */
 -     public function get_extensions()
 -     {
 -         if ($this->exts)
 -             return $this->exts;
 - 
 -         if (!$this->sieve)
 -             return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -         $ext = $this->sieve->getExtensions();
 - 
 -         if (is_a($ext, 'PEAR_Error')) {
 -             return array();
 -         }
 - 
 -         // we're working on lower-cased names
 -         $ext = array_map('strtolower', (array) $ext);
 - 
 -         if ($this->script) {
 -             $supported = $this->script->get_extensions();
 -             foreach ($ext as $idx => $ext_name)
 -                 if (!in_array($ext_name, $supported))
 -                     unset($ext[$idx]);
 -         }
 - 
 -         return array_values($ext);
 -     }
 - 
 -     /**
 -      * Gets list of scripts from server
 -      */
 -     public function get_scripts()
 -     {
 -         if (!$this->list) {
 - 
 -             if (!$this->sieve)
 -                 return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -             $list = $this->sieve->listScripts();
 - 
 -             if (is_a($list, 'PEAR_Error')) {
 -                 return $this->_set_error(self::ERROR_OTHER);
 -             }
 - 
 -             $this->list = $list;
 -         }
 - 
 -         return $this->list;
 -     }
 - 
 -     /**
 -      * Returns active script name
 -      */
 -     public function get_active()
 -     {
 -         if (!$this->sieve)
 -             return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -         return $this->sieve->getActive();
 -     }
 - 
 -     /**
 -      * Loads script by name
 -      */
 -     public function load($name)
 -     {
 -         if (!$this->sieve)
 -             return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -         if ($this->current == $name)
 -             return true;
 - 
 -         $script = $this->sieve->getScript($name);
 - 
 -         if (is_a($script, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_OTHER);
 -         }
 - 
 -         // try to parse from Roundcube format
 -         $this->script = $this->_parse($script);
 - 
 -         $this->current = $name;
 - 
 -         return true;
 -     }
 - 
 -     /**
 -      * Loads script from text content
 -      */
 -     public function load_script($script)
 -     {
 -         if (!$this->sieve)
 -             return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -         // try to parse from Roundcube format
 -         $this->script = $this->_parse($script);
 -     }
 - 
 -     /**
 -      * Creates rcube_sieve_script object from text script
 -      */
 -     private function _parse($txt)
 -     {
 -         // parse
 -         $script = new rcube_sieve_script($txt, $this->exts);
 - 
 -         // fix/convert to Roundcube format
 -         if (!empty($script->content)) {
 -             // replace all elsif with if+stop, we support only ifs
 -             foreach ($script->content as $idx => $rule) {
 -                 if (empty($rule['type']) || !preg_match('/^(if|elsif|else)$/', $rule['type'])) {
 -                     continue;
 -                 }
 - 
 -                 $script->content[$idx]['type'] = 'if';
 - 
 -                 // 'stop' not found?
 -                 foreach ($rule['actions'] as $action) {
 -                     if (preg_match('/^(stop|vacation)$/', $action['type'])) {
 -                         continue 2;
 -                     }
 -                 }
 -                 if (!empty($script->content[$idx+1]) && $script->content[$idx+1]['type'] != 'if') {
 -                     $script->content[$idx]['actions'][] = array('type' => 'stop');
 -                 }
 -             }
 -         }
 - 
 -         return $script;
 -     }
 - 
 -     /**
 -      * Gets specified script as text
 -      */
 -     public function get_script($name)
 -     {
 -         if (!$this->sieve)
 -             return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -         $content = $this->sieve->getScript($name);
 - 
 -         if (is_a($content, 'PEAR_Error')) {
 -             return $this->_set_error(self::ERROR_OTHER);
 -         }
 - 
 -         return $content;
 -     }
 - 
 -     /**
 -      * Creates empty script or copy of other script
 -      */
 -     public function copy($name, $copy)
 -     {
 -         if (!$this->sieve)
 -             return $this->_set_error(self::ERROR_INTERNAL);
 - 
 -         if ($copy) {
 -             $content = $this->sieve->getScript($copy);
 - 
 -             if (is_a($content, 'PEAR_Error')) {
 -                 return $this->_set_error(self::ERROR_OTHER);
 -             }
 -         }
 - 
 - 
 -         return $this->save_script($name, $content);
 -     }
 - 
 -     private function _set_error($error)
 -     {
 -         $this->error = $error;
 -         return false;
 -     }
 - 
 -     /**
 -      * This is our own debug handler for connection
 -      */
 -     public function debug_handler(&$sieve, $message)
 -     {
 -         rcube::write_log('sieve', preg_replace('/\r\n$/', '', $message));
 -     }
 - }
 
 
  |