From d0b973cf6aed4a7cb705f706624d25b31d19ed52 Mon Sep 17 00:00:00 2001 From: svncommit <devs@roundcube.net> Date: Thu, 18 Sep 2008 07:54:14 -0400 Subject: [PATCH] Bind cookie gotten over HTTPS to HTTPS only (#1485336). --- program/lib/imap.inc | 168 ++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 103 insertions(+), 65 deletions(-) diff --git a/program/lib/imap.inc b/program/lib/imap.inc index 42aa0fa..17197d8 100644 --- a/program/lib/imap.inc +++ b/program/lib/imap.inc @@ -52,8 +52,6 @@ - $ICL_SSL is not boolean anymore but contains the connection schema (ssl or tls) - Removed some debuggers (echo ...) File altered by Aleksander Machniak <alec@alec.pl> - - RFC3501 [7.1] don't call CAPABILITY if was returned in server - optional resposne in iil_Connect() - trim(chop()) replaced by trim() - added iil_Escape() with support for " and \ in folder names - support \ character in username in iil_C_Login() @@ -62,6 +60,12 @@ - removed hardcoded data size in iil_ReadLine() - added iil_PutLine() wrapper for fputs() - code cleanup and identation fixes + - removed flush() calls in iil_C_HandlePartBody() to prevent from memory leak (#1485187) + - don't return "??" from iil_C_GetQuota() + - RFC3501 [7.1] don't call CAPABILITY if was returned in server + optional resposne in iil_Connect(), added iil_C_GetCapability() + - remove 'undisclosed-recipients' string from 'To' header + - iil_C_HandlePartBody(): added 6th argument and fixed endless loop ********************************************************/ @@ -124,6 +128,7 @@ var $delimiter; var $capability = array(); var $permanentflags = array(); + var $capability_readed = false; } /** @@ -292,6 +297,40 @@ return strtr($string, array('"'=>'\\"', '\\' => '\\\\')); } +function iil_C_GetCapability(&$conn, $name) +{ + if (in_array($name, $conn->capability)) { + return true; + } + else if ($conn->capability_readed) { + return false; + } + + // get capabilities (only once) because initial + // optional CAPABILITY response may differ + $conn->capability = array(); + + iil_PutLine($conn->fp, "cp01 CAPABILITY"); + do { + $line = trim(iil_ReadLine($conn->fp, 1024)); + $a = explode(' ', $line); + if ($line[0] == '*') { + while (list($k, $w) = each($a)) { + if ($w != '*' && $w != 'CAPABILITY') + $conn->capability[] = strtoupper($w); + } + } + } while ($a[0] != 'cp01'); + + $conn->capability_readed = true; + + if (in_array($name, $conn->capability)) { + return true; + } + + return false; +} + function iil_C_Authenticate(&$conn, $user, $pass, $encChallenge) { $ipad = ''; @@ -396,7 +435,7 @@ function iil_C_NameSpace(&$conn) { global $my_prefs; - if (!in_array('NAMESPACE', $conn->capability)) { + if (!iil_C_GetCapability($conn, 'NAMESPACE')) { return false; } @@ -511,42 +550,24 @@ } $iil_error .= "Socket connection established\r\n"; - $line = iil_ReadLine($conn->fp, 1024); + $line = iil_ReadLine($conn->fp, 4096); // RFC3501 [7.1] optional CAPABILITY response - // commented out, because it's not working always as should -// if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) { -// $conn->capability = explode(' ', $matches[1]); -// } else { - iil_PutLine($conn->fp, "cp01 CAPABILITY"); - do { - $line = trim(iil_ReadLine($conn->fp, 1024)); + if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) { + $conn->capability = explode(' ', strtoupper($matches[1])); + } - $conn->message .= "$line\n"; - - $a = explode(' ', $line); - if ($line[0] == '*') { - while (list($k, $w) = each($a)) { - if ($w != '*' && $w != 'CAPABILITY') - $conn->capability[] = $w; - } - } - } while ($a[0] != 'cp01'); -// } + $conn->message .= $line; if (strcasecmp($auth_method, "check") == 0) { //check for supported auth methods - - //default to plain text auth - $auth_method = 'plain'; - - //check for CRAM-MD5 - foreach ($conn->capability as $c) - if (strcasecmp($c, 'AUTH=CRAM_MD5') == 0 || - strcasecmp($c, 'AUTH=CRAM-MD5') == 0) { - $auth_method = 'auth'; - break; - } + if (iil_C_GetCapability($conn, 'AUTH=CRAM-MD5') || iil_C_GetCapability($conn, 'AUTH=CRAM_MD5')) { + $auth_method = 'auth'; + } + else { + //default to plain text auth + $auth_method = 'plain'; + } } if (strcasecmp($auth_method, 'auth') == 0) { @@ -1657,7 +1678,7 @@ $result[$id]->from = $string; break; case 'to': - $result[$id]->to = $string; + $result[$id]->to = preg_replace('/undisclosed-recipients:[;,]*/', '', $string); break; case 'subject': $result[$id]->subject = $string; @@ -2333,19 +2354,19 @@ return $result; } -function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part, $mode) { +function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part, $mode, $file=NULL) { /* modes: - 1: return string + 1: return string (or write to $file pointer) 2: print - 3: base64 and print + 3: base64 and print (or write to $file pointer) */ $fp = $conn->fp; $result = false; if (($part == 0) || empty($part)) { - $part = 'TEXT'; + $part = 'TEXT'; } - + if (iil_C_Select($conn, $mailbox)) { $reply_key = '* ' . $id; @@ -2379,8 +2400,11 @@ if ($mode == 2) { echo $result; } else if ($mode == 3) { - echo base64_decode($result); - } + if ($file) + fwrite($file, base64_decode($result)); + else + echo base64_decode($result); + } } else if ($line[$len-1] == '}') { //multi-line request, find sizes of content and receive that many bytes $from = strpos($line, '{') + 1; @@ -2388,34 +2412,47 @@ $len = $to - $from; $sizeStr = substr($line, $from, $len); $bytes = (int)$sizeStr; - $received = 0; - while ($received < $bytes) { - $remaining = $bytes - $received; - $line = iil_ReadLine($fp, 1024); + while ($bytes > 0) { + $line = iil_ReadLine($fp, 1024); $len = strlen($line); - if ($len > $remaining) { - $line = substr($line, 0, $remaining); + if ($len > $bytes) { + $line = substr($line, 0, $bytes); } - $received += strlen($line); + $bytes -= strlen($line); + if ($mode == 1) { - $result .= rtrim($line, "\t\r\n\0\x0B") . "\n"; + if ($file) + fwrite($file, rtrim($line, "\t\r\n\0\x0B") . "\n"); + else + $result .= rtrim($line, "\t\r\n\0\x0B") . "\n"; } else if ($mode == 2) { - echo rtrim($line, "\t\r\n\0\x0B") . "\n"; flush(); + echo rtrim($line, "\t\r\n\0\x0B") . "\n"; } else if ($mode == 3) { - echo base64_decode($line); flush(); - } + if ($file) + fwrite($file, base64_decode($line)); + else + echo base64_decode($line); + } } } - // read in anything up until 'til last line + // read in anything up until last line do { $line = iil_ReadLine($fp, 1024); } while (!iil_StartsWith($line, $key)); + if ($mode == 3 && $file) { + return true; + } + if ($result) { $result = rtrim($result, "\t\r\n\0\x0B"); - return $result; // substr($result, 0, strlen($result)-1); + if ($file) { + fwrite($file, $result); + return true; + } + return $result; // substr($result, 0, strlen($result)-1); } return false; @@ -2424,13 +2461,18 @@ } if ($mode==1) { + if ($file) { + fwrite($file, $result); + return true; + } return $result; } - return $received; + + return false; } -function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part) { - return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1); +function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part, $file=NULL) { + return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1, $file); } function iil_C_PrintPartBody(&$conn, $mailbox, $id, $part) { @@ -2576,7 +2618,7 @@ $line = iil_ReadLine($fp, 5000); $line = iil_MultLine($fp, $line); list(, $index, $cmd, $rest) = explode(' ', $line); - if ($cmd != 'FETCH' || $index == $id) + if ($cmd != 'FETCH' || $index == $id || preg_match("/^$key/", $line)) $result .= $line; } while (!preg_match("/^$key/", $line)); @@ -2620,13 +2662,9 @@ $parts = explode(' ', $quota_line); $storage_part = array_search('STORAGE', $parts); if ($storage_part > 0) { - $result = array(); - $used = $parts[$storage_part+1]; - $total = $parts[$storage_part+2]; - - $result['used'] = $used; - $result['total'] = (empty($total)?"??":$total); - $result['percent'] = (empty($total)?"??":round(($used/$total)*100)); + $result['used'] = intval($parts[$storage_part+1]); + $result['total'] = intval($parts[$storage_part+2]); + $result['percent'] = min(100, round(($result['used']/max(1,$result['total']))*100)); $result['free'] = 100 - $result['percent']; } } -- Gitblit v1.9.1