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