summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2008-10-30 09:17:36 +0000
committeralecpl <alec@alec.pl>2008-10-30 09:17:36 +0000
commitd2993ee4db2ad20b2feebb04060acbe15d890cda (patch)
tree75335dbe150e2ec14892f71f499878a0ca5f40dd
parentd245963846993a5ab5ac0572f7e988f0865c678e (diff)
- added BYE response simple support to prevent from endless loops in imap.inc (#1483956)
-rw-r--r--CHANGELOG1
-rw-r--r--index.php2
-rw-r--r--program/lib/imap.inc117
3 files changed, 72 insertions, 48 deletions
diff --git a/CHANGELOG b/CHANGELOG
index cbf94dbf3..fe8bb5c95 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@ CHANGELOG RoundCube Webmail
2008/10/29 (alec)
----------
- Fix problem with numeric folder names (#1485527)
+- Added BYE response simple support to prevent from endless loops in imap.inc (#1483956)
2008/10/27 (alec)
----------
diff --git a/index.php b/index.php
index a080ef585..92223d22f 100644
--- a/index.php
+++ b/index.php
@@ -100,7 +100,7 @@ if ($RCMAIL->action=='login' && $RCMAIL->task=='mail') {
$OUTPUT->redirect();
}
else {
- $OUTPUT->show_message($IMAP->error_code == -1 ? 'imaperror' : 'loginfailed', 'warning');
+ $OUTPUT->show_message($IMAP->error_code == -1 ? 'loginfailed' : 'imaperror', 'warning');
$RCMAIL->kill_session();
}
}
diff --git a/program/lib/imap.inc b/program/lib/imap.inc
index c78e67ad5..24abd697d 100644
--- a/program/lib/imap.inc
+++ b/program/lib/imap.inc
@@ -68,6 +68,8 @@
- iil_C_HandlePartBody(): added 6th argument and fixed endless loop
- added iil_PutLineC()
- fixed iil_C_Sort() to support very long and/or divided responses
+ - added BYE response simple support for endless loop prevention
+ - added 3rd argument in iil_StartsWith* functions
********************************************************/
@@ -286,13 +288,15 @@ function iil_ParseResult($string) {
return -1;
} else if (strcasecmp($a[1], 'BAD') == 0) {
return -2;
+ } else if (strcasecmp($a[1], 'BYE') == 0) {
+ return -3;
}
}
- return -3;
+ return -4;
}
// check if $string starts with $match
-function iil_StartsWith($string, $match) {
+function iil_StartsWith($string, $match, $bye=false) {
$len = strlen($match);
if ($len == 0) {
return false;
@@ -300,10 +304,13 @@ function iil_StartsWith($string, $match) {
if (strncmp($string, $match, $len) == 0) {
return true;
}
+ if ($bye && strncmp($string, '* BYE ', 6) == 0) {
+ return true;
+ }
return false;
}
-function iil_StartsWithI($string, $match) {
+function iil_StartsWithI($string, $match, $bye=false) {
$len = strlen($match);
if ($len == 0) {
return false;
@@ -311,6 +318,9 @@ function iil_StartsWithI($string, $match) {
if (strncasecmp($string, $match, $len) == 0) {
return true;
}
+ if ($bye && strncmp($string, '* BYE ', 6) == 0) {
+ return true;
+ }
return false;
}
@@ -381,15 +391,20 @@ function iil_C_Authenticate(&$conn, $user, $pass, $encChallenge) {
$line = iil_ReadLine($conn->fp, 1024);
// process result
- if (iil_ParseResult($line) == 0) {
+ $result = iil_ParseResult($line);
+ if ($result == 0) {
$conn->error .= '';
$conn->errorNum = 0;
return $conn->fp;
}
+
+ if ($result == -3) fclose($conn->fp); // BYE response
+
$conn->error .= 'Authentication for ' . $user . ' failed (AUTH): "';
$conn->error .= htmlspecialchars($line) . '"';
- $conn->errorNum = -2;
- return false;
+ $conn->errorNum = $result;
+
+ return $result;
}
function iil_C_Login(&$conn, $user, $password) {
@@ -401,20 +416,22 @@ function iil_C_Login(&$conn, $user, $password) {
if ($line === false) {
break;
}
- } while (!iil_StartsWith($line, "a001 "));
- $a = explode(' ', $line);
- if (strcmp($a[1], 'OK') == 0) {
- $result = $conn->fp;
+ } while (!iil_StartsWith($line, 'a001 ', true));
+
+ // process result
+ $result = iil_ParseResult($line);
+
+ if ($result == 0) {
$conn->error .= '';
$conn->errorNum = 0;
- return $result;
+ return $conn->fp;
}
- $result = false;
+
fclose($conn->fp);
$conn->error .= 'Authentication for ' . $user . ' failed (LOGIN): "';
$conn->error .= htmlspecialchars($line)."\"";
- $conn->errorNum = -2;
+ $conn->errorNum = $result;
return $result;
}
@@ -472,7 +489,7 @@ function iil_C_NameSpace(&$conn) {
$i = 0;
$data = iil_ParseNamespace2(substr($line,11), $i, 0, 0);
}
- } while (!iil_StartsWith($line, "ns1"));
+ } while (!iil_StartsWith($line, 'ns1', true));
if (!is_array($data)) {
return false;
@@ -504,10 +521,6 @@ function iil_Connect($host, $user, $password) {
$iil_error = '';
$iil_errornum = 0;
- //strip slashes
- // $user = stripslashes($user);
- // $password = stripslashes($password);
-
//set auth method
$auth_method = 'plain';
if (func_num_args() >= 4) {
@@ -543,15 +556,18 @@ function iil_Connect($host, $user, $password) {
//check input
if (empty($host)) {
- $iil_error .= "Invalid host\n";
+ $iil_error = "Empty host";
+ $iil_errornum = -1;
+ return false;
}
if (empty($user)) {
- $iil_error .= "Invalid user\n";
+ $iil_error = "Empty user";
+ $iil_errornum = -1;
+ return false;
}
if (empty($password)) {
- $iil_error .= "Invalid password\n";
- }
- if (!empty($iil_error)) {
+ $iil_error = "Empty password";
+ $iil_errornum = -1;
return false;
}
if (!$ICL_PORT) {
@@ -606,7 +622,13 @@ function iil_Connect($host, $user, $password) {
//got a challenge string, try CRAM-5
$result = iil_C_Authenticate($conn, $user, $password, substr($line,2));
-
+
+ // stop if server sent BYE response
+ if($result == -3) {
+ $iil_error = $conn->error;
+ $iil_errornum = $conn->errorNum;
+ return false;
+ }
$conn->message .= "Tried CRAM-MD5: $result \n";
} else {
$conn->message .='No challenge ('.htmlspecialchars($line)."), try plain\n";
@@ -617,12 +639,12 @@ function iil_Connect($host, $user, $password) {
if ((!$result)||(strcasecmp($auth, "plain") == 0)) {
//do plain text auth
$result = iil_C_Login($conn, $user, $password);
- $conn->message.="Tried PLAIN: $result \n";
+ $conn->message .= "Tried PLAIN: $result \n";
}
$conn->message .= $auth;
- if ($result) {
+ if (!is_int($result)) {
iil_C_Namespace($conn);
return $conn;
} else {
@@ -752,8 +774,8 @@ function iil_CheckForRecent($host, $user, $password, $mailbox) {
$a=explode(' ', $line);
if (($a[0] == '*') && (strcasecmp($a[2], 'RECENT') == 0)) {
$result = (int) $a[1];
- }
- } while (!iil_StartsWith($a[0], 'a002'));
+ }
+ } while (!iil_StartsWith($a[0], 'a002', true));
iil_PutLine($fp, "a003 LOGOUT");
fclose($fp);
@@ -790,7 +812,7 @@ function iil_C_Select(&$conn, $mailbox) {
else if (preg_match('/\[?PERMANENTFLAGS\s+\(([^\)]+)\)\]/U', $line, $match)) {
$conn->permanentflags = explode(' ', $match[1]);
}
- } while (!iil_StartsWith($line, 'sel1'));
+ } while (!iil_StartsWith($line, 'sel1', true));
$a = explode(' ', $line);
@@ -838,7 +860,7 @@ function iil_SplitHeaderLine($string) {
function iil_StrToTime($str) {
$IMAP_MONTHS = $GLOBALS['IMAP_MONTHS'];
- $IMAP_SERVER_TZ = $GLOBALS['IMAP_SERVER_TR'];
+ $IMAP_SERVER_TZ = $GLOBALS['IMAP_SERVER_TZ'];
if ($str) {
$time1 = strtotime($str);
@@ -917,7 +939,7 @@ function iil_C_Sort(&$conn, $mailbox, $field, $add='', $is_uid=FALSE,
} else if (preg_match('/^[0-9 ]+$/', $line)) {
$data .= $line;
}
- } while ($line[0]!='s');
+ } while (!iil_StartsWith($line, 's ', true));
if (empty($data)) {
$conn->error = $line;
@@ -1039,7 +1061,7 @@ function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
//one line response, not expected so ignore
}
*/
- } while (!iil_StartsWith($line, $key));
+ } while (!iil_StartsWith($line, $key, true));
}else if ($mode == 6) {
@@ -1070,7 +1092,7 @@ function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
} else {
$a = explode(' ', $line);
}
- } while (!iil_StartsWith($a[0], $key));
+ } while (!iil_StartsWith($a[0], $key, true));
} else {
if ($mode >= 3) {
$field_name = 'FLAGS';
@@ -1112,7 +1134,7 @@ function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
$result[$id] = (strpos($haystack, $index_field) > 0 ? "F" : "N");
}
}
- } while (!iil_StartsWith($line, $key));
+ } while (!iil_StartsWith($line, $key, true));
}
//check number of elements...
@@ -1951,7 +1973,7 @@ function iil_C_Expunge(&$conn, $mailbox) {
if ($line[0] == '*') {
$c++;
}
- } while (!iil_StartsWith($line, 'exp1'));
+ } while (!iil_StartsWith($line, 'exp1', true));
if (iil_ParseResult($line) == 0) {
$conn->selected = ''; //state has changed, need to reselect
@@ -1983,7 +2005,7 @@ function iil_C_ModFlag(&$conn, $mailbox, $messages, $flag, $mod) {
if ($line[0] == '*') {
$c++;
}
- } while (!iil_StartsWith($line, 'flg'));
+ } while (!iil_StartsWith($line, 'flg', true));
if (iil_ParseResult($line) == 0) {
iil_C_ExpireCachedItems($conn, $mailbox, $messages);
@@ -2093,7 +2115,7 @@ function iil_C_Search(&$conn, $folder, $criteria) {
$str = trim(substr($line, 8));
$messages = explode(' ', $str);
}
- } while (!iil_StartsWith($line, 'srch1'));
+ } while (!iil_StartsWith($line, 'srch1', true));
$result_code = iil_ParseResult($line);
if ($result_code == 0) {
@@ -2151,7 +2173,7 @@ function iil_C_GetHierarchyDelimiter(&$conn) {
$delimiter = str_replace('"', '', $a[count($a)-2]);
}
}
- } while (!iil_StartsWith($line, 'ghd'));
+ } while (!iil_StartsWith($line, 'ghd', true));
if (strlen($delimiter)>0) {
return $delimiter;
@@ -2166,7 +2188,7 @@ function iil_C_GetHierarchyDelimiter(&$conn) {
$i = 0;
$data = iil_ParseNamespace2(substr($line,11), $i, 0, 0);
}
- } while (!iil_StartsWith($line, 'ns1'));
+ } while (!iil_StartsWith($line, 'ns1', true));
if (!is_array($data)) {
return false;
@@ -2234,7 +2256,7 @@ function iil_C_ListMailboxes(&$conn, $ref, $mailbox) {
// is it a container?
$i++;
}
- } while (!iil_StartsWith($line, 'lmb'));
+ } while (!iil_StartsWith($line, 'lmb', true));
if (is_array($folders)) {
if (!empty($ref)) {
@@ -2303,7 +2325,7 @@ function iil_C_ListSubscribed(&$conn, $ref, $mailbox) {
// is it a container?
$i++;
}
- } while (!iil_StartsWith($line, 'lsb'));
+ } while (!iil_StartsWith($line, 'lsb', true));
if (is_array($folders)) {
if (!empty($ref)) {
@@ -2359,14 +2381,14 @@ function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $part) {
$line = chop(iil_ReadLine($fp, 200));
$a = explode(' ', $line);
if (($line[0] == '*') && ($a[2] == 'FETCH')
- && ($line[strlen($line)-1] != ')')) {
+ && ($line[strlen($line)-1] != ')')) {
$line=iil_ReadLine($fp, 300);
while (trim($line) != ')') {
$result .= $line;
$line=iil_ReadLine($fp, 300);
}
}
- } while (strcmp($a[0], $key) != 0);
+ } while (strcmp($a[0], $key) != 0 && ($a[0] != '*' || $a[1] != 'BYE'));
}
return $result;
@@ -2402,8 +2424,9 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part, $mode, $file=NULL) {
$a = explode(' ', $line);
} while ($a[2] != 'FETCH');
$len = strlen($line);
-
- if ($line[$len-1] == ')') {
+
+ // handle empty "* X FETCH ()" response
+ if ($line[$len-1] == ')' && $line[$len-2] != '(') {
// one line response, get everything between first and last quotes
if (substr($line, -4, 3) == 'NIL') {
// NIL response
@@ -2458,7 +2481,7 @@ function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part, $mode, $file=NULL) {
// read in anything up until last line
do {
$line = iil_ReadLine($fp, 1024);
- } while (!iil_StartsWith($line, $key));
+ } while (!iil_StartsWith($line, $key, true));
if ($mode == 3 && $file) {
return true;
@@ -2671,7 +2694,7 @@ function iil_C_GetQuota(&$conn) {
if (iil_StartsWith($line, '* QUOTA ')) {
$quota_line = $line;
}
- } while (!iil_StartsWith($line, 'QUOT1'));
+ } while (!iil_StartsWith($line, 'QUOT1', true));
}
//return false if not found, parse if found