| | |
| | | * 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 version 2 |
| | | * as published by the Free Software Foundation. |
| | | * 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, write to the Free Software Foundation, Inc., |
| | | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| | | * 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 |
| | | |
| | | define('SIEVE_ERROR_CONNECTION', 1); |
| | | define('SIEVE_ERROR_LOGIN', 2); |
| | | define('SIEVE_ERROR_NOT_EXISTS', 3); // script not exists |
| | | define('SIEVE_ERROR_INSTALL', 4); // script installation |
| | | define('SIEVE_ERROR_ACTIVATE', 5); // script activation |
| | | define('SIEVE_ERROR_DELETE', 6); // script deletion |
| | | define('SIEVE_ERROR_INTERNAL', 7); // internal error |
| | | define('SIEVE_ERROR_DEACTIVATE', 8); // script activation |
| | | define('SIEVE_ERROR_OTHER', 255); // other/unknown error |
| | | |
| | | |
| | | class rcube_sieve |
| | | { |
| | |
| | | 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 |
| | | |
| | | |
| | | /** |
| | |
| | | * @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) |
| | | $auth_cid=null, $auth_pw=null, $options=array()) |
| | | { |
| | | $this->sieve = new Net_Sieve(); |
| | | |
| | |
| | | $this->sieve->setDebug(true, array($this, 'debug_handler')); |
| | | } |
| | | |
| | | if (PEAR::isError($this->sieve->connect($host, $port, null, $usetls))) { |
| | | return $this->_set_error(SIEVE_ERROR_CONNECTION); |
| | | if (PEAR::isError($this->sieve->connect($host, $port, $options, $usetls))) { |
| | | return $this->_set_error(self::ERROR_CONNECTION); |
| | | } |
| | | |
| | | if (!empty($auth_cid)) { |
| | |
| | | if (PEAR::isError($this->sieve->login($username, $password, |
| | | $auth_type ? strtoupper($auth_type) : null, $authz)) |
| | | ) { |
| | | return $this->_set_error(SIEVE_ERROR_LOGIN); |
| | | return $this->_set_error(self::ERROR_LOGIN); |
| | | } |
| | | |
| | | $this->exts = $this->get_extensions(); |
| | | $this->exts = $this->get_extensions(); |
| | | |
| | | // disable features by config |
| | | if (!empty($disabled)) { |
| | |
| | | public function save($name = null) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if (!$this->script) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if (!$name) |
| | | $name = $this->current; |
| | |
| | | $script = '/* empty script */'; |
| | | |
| | | if (PEAR::isError($this->sieve->installScript($name, $script))) |
| | | return $this->_set_error(SIEVE_ERROR_INSTALL); |
| | | return $this->_set_error(self::ERROR_INSTALL); |
| | | |
| | | return true; |
| | | } |
| | |
| | | public function save_script($name, $content = null) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if (!$content) |
| | | $content = '/* empty script */'; |
| | | |
| | | if (PEAR::isError($this->sieve->installScript($name, $content))) |
| | | return $this->_set_error(SIEVE_ERROR_INSTALL); |
| | | return $this->_set_error(self::ERROR_INSTALL); |
| | | |
| | | return true; |
| | | } |
| | |
| | | public function activate($name = null) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if (!$name) |
| | | $name = $this->current; |
| | | |
| | | if (PEAR::isError($this->sieve->setActive($name))) |
| | | return $this->_set_error(SIEVE_ERROR_ACTIVATE); |
| | | return $this->_set_error(self::ERROR_ACTIVATE); |
| | | |
| | | return true; |
| | | } |
| | |
| | | public function deactivate() |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if (PEAR::isError($this->sieve->setActive(''))) |
| | | return $this->_set_error(SIEVE_ERROR_DEACTIVATE); |
| | | return $this->_set_error(self::ERROR_DEACTIVATE); |
| | | |
| | | return true; |
| | | } |
| | |
| | | public function remove($name = null) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if (!$name) |
| | | $name = $this->current; |
| | |
| | | // script must be deactivated first |
| | | if ($name == $this->sieve->getActive()) |
| | | if (PEAR::isError($this->sieve->setActive(''))) |
| | | return $this->_set_error(SIEVE_ERROR_DELETE); |
| | | return $this->_set_error(self::ERROR_DELETE); |
| | | |
| | | if (PEAR::isError($this->sieve->removeScript($name))) |
| | | return $this->_set_error(SIEVE_ERROR_DELETE); |
| | | return $this->_set_error(self::ERROR_DELETE); |
| | | |
| | | if ($name == $this->current) |
| | | $this->current = null; |
| | |
| | | return $this->exts; |
| | | |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | $ext = $this->sieve->getExtensions(); |
| | | |
| | | if (PEAR::isError($ext)) { |
| | | return array(); |
| | | } |
| | | |
| | | // we're working on lower-cased names |
| | | $ext = array_map('strtolower', (array) $ext); |
| | | |
| | |
| | | if (!$this->list) { |
| | | |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | $list = $this->sieve->listScripts(); |
| | | |
| | | if (PEAR::isError($list)) |
| | | return $this->_set_error(SIEVE_ERROR_OTHER); |
| | | return $this->_set_error(self::ERROR_OTHER); |
| | | |
| | | $this->list = $list; |
| | | } |
| | |
| | | public function get_active() |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | return $this->sieve->getActive(); |
| | | } |
| | |
| | | public function load($name) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if ($this->current == $name) |
| | | return true; |
| | |
| | | $script = $this->sieve->getScript($name); |
| | | |
| | | if (PEAR::isError($script)) |
| | | return $this->_set_error(SIEVE_ERROR_OTHER); |
| | | return $this->_set_error(self::ERROR_OTHER); |
| | | |
| | | // try to parse from Roundcube format |
| | | $this->script = $this->_parse($script); |
| | |
| | | public function load_script($script) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | // try to parse from Roundcube format |
| | | $this->script = $this->_parse($script); |
| | |
| | | public function get_script($name) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | $content = $this->sieve->getScript($name); |
| | | |
| | | if (PEAR::isError($content)) |
| | | return $this->_set_error(SIEVE_ERROR_OTHER); |
| | | return $this->_set_error(self::ERROR_OTHER); |
| | | |
| | | return $content; |
| | | } |
| | |
| | | public function copy($name, $copy) |
| | | { |
| | | if (!$this->sieve) |
| | | return $this->_set_error(SIEVE_ERROR_INTERNAL); |
| | | return $this->_set_error(self::ERROR_INTERNAL); |
| | | |
| | | if ($copy) { |
| | | $content = $this->sieve->getScript($copy); |
| | | |
| | | if (PEAR::isError($content)) |
| | | return $this->_set_error(SIEVE_ERROR_OTHER); |
| | | return $this->_set_error(self::ERROR_OTHER); |
| | | } |
| | | |
| | | return $this->save_script($name, $content); |
| | |
| | | */ |
| | | public function debug_handler(&$sieve, $message) |
| | | { |
| | | write_log('sieve', preg_replace('/\r\n$/', '', $message)); |
| | | rcube::write_log('sieve', preg_replace('/\r\n$/', '', $message)); |
| | | } |
| | | } |