From 8d8f7a7b8e7ea8464aa807611b3db320fab12156 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Thu, 05 Apr 2012 03:51:20 -0400
Subject: [PATCH] - Larry skin support
---
plugins/managesieve/lib/Net/Sieve.php | 170 ++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 115 insertions(+), 55 deletions(-)
diff --git a/plugins/managesieve/lib/Net/Sieve.php b/plugins/managesieve/lib/Net/Sieve.php
index be52540..a8e36d8 100644
--- a/plugins/managesieve/lib/Net/Sieve.php
+++ b/plugins/managesieve/lib/Net/Sieve.php
@@ -39,7 +39,7 @@
* @copyright 2002-2003 Richard Heyes
* @copyright 2006-2008 Anish Mistry
* @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version SVN: $Id: Sieve.php 289313 2009-10-07 22:26:33Z yunosh $
+ * @version SVN: $Id: Sieve.php 300898 2010-07-01 09:49:02Z yunosh $
* @link http://pear.php.net/package/Net_Sieve
*/
@@ -83,7 +83,7 @@
* @copyright 2002-2003 Richard Heyes
* @copyright 2006-2008 Anish Mistry
* @license http://www.opensource.org/licenses/bsd-license.php BSD
- * @version Release: @package_version@
+ * @version Release: 1.3.0
* @link http://pear.php.net/package/Net_Sieve
* @link http://www.ietf.org/rfc/rfc3028.txt RFC 3028 (Sieve: A Mail
* Filtering Language)
@@ -107,7 +107,7 @@
*
* @var array
*/
- var $_supportedSASLAuthMethods = array('DIGEST-MD5', 'CRAM-MD5');
+ var $supportedSASLAuthMethods = array('DIGEST-MD5', 'CRAM-MD5');
/**
* The socket handle.
@@ -204,11 +204,13 @@
* @param boolean $useTLS Use TLS if available.
* @param array $options Additional options for
* stream_context_create().
+ * @param mixed $handler A callback handler for the debug output.
*/
function Net_Sieve($user = null, $pass = null, $host = 'localhost',
- $port = 2000, $logintype = '', $euser = '', $debug = false,
- $bypassAuth = false, $useTLS = true, $options = null
- ) {
+ $port = 2000, $logintype = '', $euser = '',
+ $debug = false, $bypassAuth = false, $useTLS = true,
+ $options = null, $handler = null)
+ {
$this->_state = NET_SIEVE_STATE_DISCONNECTED;
$this->_data['user'] = $user;
$this->_data['pass'] = $pass;
@@ -217,10 +219,10 @@
$this->_data['logintype'] = $logintype;
$this->_data['euser'] = $euser;
$this->_sock = new Net_Socket();
- $this->_debug = $debug;
$this->_bypassAuth = $bypassAuth;
$this->_useTLS = $useTLS;
$this->_options = $options;
+ $this->setDebug($debug, $handler);
/* Try to include the Auth_SASL package. If the package is not
* available, we disable the authentication methods that depend upon
@@ -294,6 +296,13 @@
*/
function connect($host, $port, $options = null, $useTLS = true)
{
+ $this->_data['host'] = $host;
+ $this->_data['port'] = $port;
+ $this->_useTLS = $useTLS;
+ if (!empty($options) && is_array($options)) {
+ $this->_options = array_merge($this->_options, $options);
+ }
+
if (NET_SIEVE_STATE_DISCONNECTED != $this->_state) {
return PEAR::raiseError('Not currently in DISCONNECTED state', 1);
}
@@ -357,6 +366,12 @@
*/
function login($user, $pass, $logintype = null, $euser = '', $bypassAuth = false)
{
+ $this->_data['user'] = $user;
+ $this->_data['pass'] = $pass;
+ $this->_data['logintype'] = $logintype;
+ $this->_data['euser'] = $euser;
+ $this->_bypassAuth = $bypassAuth;
+
if (NET_SIEVE_STATE_AUTHORISATION != $this->_state) {
return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
}
@@ -473,7 +488,9 @@
if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
return PEAR::raiseError('Not currently in TRANSACTION state', 1);
}
- if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %d', $scriptname, $size)))) {
+
+ $command = sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size);
+ if (PEAR::isError($res = $this->_doCmd($command))) {
return $res;
}
return true;
@@ -635,10 +652,10 @@
if (PEAR::isError($result = $this->_sendCmd('AUTHENTICATE "LOGIN"'))) {
return $result;
}
- if (PEAR::isError($result = $this->_doCmd('"' . base64_encode($user) . '"'))) {
+ if (PEAR::isError($result = $this->_doCmd('"' . base64_encode($user) . '"', true))) {
return $result;
}
- return $this->_doCmd('"' . base64_encode($pass) . '"');
+ return $this->_doCmd('"' . base64_encode($pass) . '"', true);
}
/**
@@ -687,10 +704,10 @@
return $response;
}
- if (PEAR::isError($result = $this->_sendStringResponse(base64_encode($param)))) {
+ if (PEAR::isError($result = $this->_sendStringResponse(base64_encode($response)))) {
return $result;
}
- if (PEAR::isError($result = $this->_doCmd())) {
+ if (PEAR::isError($result = $this->_doCmd('', true))) {
return $result;
}
if ($this->_toUpper(substr($result, 0, 2)) == 'OK') {
@@ -738,7 +755,9 @@
if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
}
- if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT "%s"', $scriptname)))) {
+
+ $command = sprintf('DELETESCRIPT %s', $this->_escape($scriptname));
+ if (PEAR::isError($res = $this->_doCmd($command))) {
return $res;
}
return true;
@@ -757,11 +776,12 @@
return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
}
- if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT "%s"', $scriptname)))) {
+ $command = sprintf('GETSCRIPT %s', $this->_escape($scriptname));
+ if (PEAR::isError($res = $this->_doCmd($command))) {
return $res;
}
- return preg_replace('/{[0-9]+}\r\n/', '', $res);
+ return preg_replace('/^{[0-9]+}\r\n/', '', $res);
}
/**
@@ -777,9 +797,12 @@
if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
}
- if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE "%s"', $scriptname)))) {
+
+ $command = sprintf('SETACTIVE %s', $this->_escape($scriptname));
+ if (PEAR::isError($res = $this->_doCmd($command))) {
return $res;
}
+
$this->_activeScript = $scriptname;
return true;
}
@@ -806,9 +829,10 @@
$res = explode("\r\n", $res);
foreach ($res as $value) {
if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) {
- $scripts[] = $matches[1];
+ $script_name = stripslashes($matches[1]);
+ $scripts[] = $script_name;
if (!empty($matches[2])) {
- $activescript = $matches[1];
+ $activescript = $script_name;
}
}
}
@@ -831,8 +855,10 @@
}
$stringLength = $this->_getLineLength($scriptdata);
+ $command = sprintf("PUTSCRIPT %s {%d+}\r\n%s",
+ $this->_escape($scriptname), $stringLength, $scriptdata);
- if (PEAR::isError($res = $this->_doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata)))) {
+ if (PEAR::isError($res = $this->_doCmd($command))) {
return $res;
}
@@ -979,6 +1005,28 @@
}
/**
+ * Receives x bytes from the server.
+ *
+ * @param int $length Number of bytes to read
+ *
+ * @return string The server response.
+ */
+ function _recvBytes($length)
+ {
+ $response = '';
+ $response_length = 0;
+
+ while ($response_length < $length) {
+ $response .= $this->_sock->read($length - $response_length);
+ $response_length = $this->_getLineLength($response);
+ }
+
+ $this->_debug("S: " . rtrim($response));
+
+ return $response;
+ }
+
+ /**
* Send a command and retrieves a response from the server.
*
* @param string $cmd The command to send.
@@ -1011,11 +1059,11 @@
if ('NO' == substr($uc_line, 0, 2)) {
// Check for string literal error message.
- if (preg_match('/^no {([0-9]+)\+?}/i', $line, $matches)) {
- $line .= str_replace(
- "\r\n", ' ', $this->_sock->read($matches[1] + 2)
- );
- $this->_debug("S: $line");
+ if (preg_match('/{([0-9]+)}$/i', $line, $matches)) {
+ $line = substr($line, 0, -(strlen($matches[1])+2))
+ . str_replace(
+ "\r\n", ' ', $this->_recvBytes($matches[1] + 2)
+ );
}
return PEAR::raiseError(trim($response . substr($line, 2)), 3);
}
@@ -1050,16 +1098,9 @@
return PEAR::raiseError(trim($response . $line), 6);
}
- if (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) {
- // Matches String Responses.
- $str_size = $matches[1] + 2;
- $line = '';
- $line_length = 0;
- while ($line_length < $str_size) {
- $line .= $this->_sock->read($str_size - $line_length);
- $line_length = $this->_getLineLength($line);
- }
- $this->_debug("S: $line");
+ if (preg_match('/^{([0-9]+)}/i', $line, $matches)) {
+ // Matches literal string responses.
+ $line = $this->_recvBytes($matches[1] + 2);
if (!$auth) {
// Receive the pending OK only if we aren't
@@ -1099,33 +1140,30 @@
if (!isset($this->_capability['sasl'])) {
return PEAR::raiseError('This server doesn\'t support any authentication methods. SASL problem?');
}
-
- $serverMethods = $this->_capability['sasl'];
+ if (!$this->_capability['sasl']) {
+ return PEAR::raiseError('This server doesn\'t support any authentication methods.');
+ }
if ($userMethod) {
- $methods = array($userMethod);
- } else {
- $methods = $this->supportedAuthMethods;
- }
-
- if (!$methods || !$serverMethods) {
+ if (in_array($userMethod, $this->_capability['sasl'])) {
+ return $userMethod;
+ }
return PEAR::raiseError(
- 'This server doesn\'t support any authentication methods.'
- );
+ sprintf('No supported authentication method found. The server supports these methods: %s, but we want to use: %s',
+ implode(', ', $this->_capability['sasl']),
+ $userMethod));
}
- foreach ($methods as $method) {
- if (in_array($method, $serverMethods)) {
+ foreach ($this->supportedAuthMethods as $method) {
+ if (in_array($method, $this->_capability['sasl'])) {
return $method;
}
}
return PEAR::raiseError(
- 'No supported authentication method found. The server supports these methods: '
- . implode(',', $serverMethods)
- . ', but we only support: '
- . implode(',', $this->supportedAuthMethods)
- );
+ sprintf('No supported authentication method found. The server supports these methods: %s, but we only support: %s',
+ implode(', ', $this->_capability['sasl']),
+ implode(', ', $this->supportedAuthMethods)));
}
/**
@@ -1147,7 +1185,13 @@
// The server should be sending a CAPABILITY response after
// negotiating TLS. Read it, and ignore if it doesn't.
- $this->_doCmd();
+ // Doesn't work with older timsieved versions
+ $regexp = '/^CYRUS TIMSIEVED V([0-9.]+)/';
+ if (!preg_match($regexp, $this->_capability['implementation'], $matches)
+ || version_compare($matches[1], '2.3.10', '>=')
+ ) {
+ $this->_doCmd();
+ }
// RFC says we need to query the server capabilities again now that we
// are under encryption.
@@ -1169,9 +1213,7 @@
*/
function _getLineLength($string)
{
- if (extension_loaded('mbstring')
- || @dl(PHP_SHLIB_PREFIX . 'mbstring.' . PHP_SHLIB_SUFFIX)
- ) {
+ if (extension_loaded('mbstring')) {
return mb_strlen($string, 'latin1');
} else {
return strlen($string);
@@ -1195,6 +1237,24 @@
}
/**
+ * Convert string into RFC's quoted-string or literal-c2s form
+ *
+ * @param string $string The string to convert.
+ *
+ * @return string Result string
+ */
+ function _escape($string)
+ {
+ // Some implementations doesn't allow UTF-8 characters in quoted-string
+ // It's safe to use literal-c2s
+ if (preg_match('/[^\x01-\x09\x0B-\x0C\x0E-\x7F]/', $string)) {
+ return sprintf("{%d+}\r\n%s", $this->_getLineLength($string), $string);
+ }
+
+ return '"' . addcslashes($string, '\\"') . '"';
+ }
+
+ /**
* Write debug text to the current debug output handler.
*
* @param string $message Debug message text.
--
Gitblit v1.9.1