From bd0551b22076b82a6d49e9f7a2b2e0c90a1b2326 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 05 Feb 2016 07:25:27 -0500
Subject: [PATCH] Secure also downloads of addressbook exports, managesieve script exports and Enigma keys exports

---
 program/lib/Roundcube/rcube_imap.php |  207 +++++----------------------------------------------
 1 files changed, 20 insertions(+), 187 deletions(-)

diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 73d32d0..5f532a5 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -62,8 +62,6 @@
     protected $sort_field = '';
     protected $sort_order = 'DESC';
     protected $struct_charset;
-    protected $uid_id_map = array();
-    protected $msg_headers = array();
     protected $search_set;
     protected $search_string = '';
     protected $search_charset = '';
@@ -984,7 +982,7 @@
 
         // gather messages from a multi-folder search
         if ($this->search_set->multi) {
-            $page_size = $this->page_size;
+            $page_size  = $this->page_size;
             $sort_field = $this->sort_field;
             $search_set = $this->search_set;
 
@@ -995,23 +993,26 @@
             $slice_length = min($page_size, $cnt - $from);
 
             // fetch resultset headers, sort and slice them
-            if (!empty($sort_field)) {
+            if (!empty($sort_field) && $search_set->get_parameters('SORT') != $sort_field) {
                 $this->sort_field = null;
-                $this->page_size = 1000;  // fetch up to 1000 matching messages per folder
-                $this->threading = false;
+                $this->page_size  = 1000;  // fetch up to 1000 matching messages per folder
+                $this->threading  = false;
 
                 $a_msg_headers = array();
                 foreach ($search_set->sets as $resultset) {
                     if (!$resultset->is_empty()) {
-                        $this->search_set = $resultset;
+                        $this->search_set     = $resultset;
                         $this->search_threads = $resultset instanceof rcube_result_thread;
-                        $a_msg_headers = array_merge($a_msg_headers, $this->list_search_messages($resultset->get_parameters('MAILBOX'), 1));
+
+                        $a_headers     =  $this->list_search_messages($resultset->get_parameters('MAILBOX'), 1);
+                        $a_msg_headers = array_merge($a_msg_headers, $a_headers);
+                        unset($a_headers);
                     }
                 }
 
                 // sort headers
                 if (!empty($a_msg_headers)) {
-                    $a_msg_headers = $this->conn->sortHeaders($a_msg_headers, $sort_field, $this->sort_order);
+                    $a_msg_headers = rcube_imap_generic::sortHeaders($a_msg_headers, $sort_field, $this->sort_order);
                 }
 
                 // store (sorted) message index
@@ -1045,7 +1046,7 @@
 
             // restore members
             $this->sort_field = $sort_field;
-            $this->page_size = $page_size;
+            $this->page_size  = $page_size;
             $this->search_set = $search_set;
 
             return $a_msg_headers;
@@ -1139,12 +1140,8 @@
                 return array();
             }
 
-            if (!$this->check_connection()) {
-                return array();
-            }
-
             // if not already sorted
-            $a_msg_headers = $this->conn->sortHeaders(
+            $a_msg_headers = rcube_imap_generic::sortHeaders(
                 $a_msg_headers, $this->sort_field, $this->sort_order);
 
             // only return the requested part of the set
@@ -2683,7 +2680,6 @@
             // really deleted from the folder
             $this->expunge_message($uids, $folder, false);
             $this->clear_messagecount($folder);
-            unset($this->uid_id_map[$folder]);
 
             // unset threads internal cache
             unset($this->icache['threads']);
@@ -2815,7 +2811,7 @@
         }
 
         // INBOX should always be available
-        if ((!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) {
+        if (!strlen($root) && (!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) {
             array_unshift($a_mboxes, 'INBOX');
         }
 
@@ -2946,7 +2942,7 @@
         }
 
         // INBOX should always be available
-        if ((!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) {
+        if (!strlen($root) && (!$filter || $filter == 'mail') && !in_array('INBOX', $a_mboxes)) {
             array_unshift($a_mboxes, 'INBOX');
         }
 
@@ -3964,8 +3960,6 @@
 
             return $res;
         }
-
-        return null;
     }
 
     /**
@@ -3986,7 +3980,6 @@
         }
 
         // @TODO: log error
-        return null;
     }
 
 
@@ -4255,19 +4248,11 @@
             $folder = $this->folder;
         }
 
-        if ($uid = array_search($id, (array)$this->uid_id_map[$folder])) {
-            return $uid;
-        }
-
         if (!$this->check_connection()) {
             return null;
         }
 
-        $uid = $this->conn->ID2UID($folder, $id);
-
-        $this->uid_id_map[$folder][$uid] = $id;
-
-        return $uid;
+        return $this->conn->ID2UID($folder, $id);
     }
 
     /**
@@ -4275,22 +4260,16 @@
      */
     protected function change_subscription($folders, $mode)
     {
-        $updated = false;
+        $updated = 0;
+        $folders = (array) $folders;
 
         if (!empty($folders)) {
             if (!$this->check_connection()) {
                 return false;
             }
 
-            foreach ((array)$folders as $i => $folder) {
-                $folders[$i] = $folder;
-
-                if ($mode == 'subscribe') {
-                    $updated = $this->conn->subscribe($folder);
-                }
-                else if ($mode == 'unsubscribe') {
-                    $updated = $this->conn->unsubscribe($folder);
-                }
+            foreach ($folders as $folder) {
+                $updated += (int) $this->conn->{$mode}($folder);
             }
         }
 
@@ -4299,7 +4278,7 @@
             $this->clear_cache('mailboxes', true);
         }
 
-        return $updated;
+        return $updated == count($folders) ? true : false;
     }
 
     /**
@@ -4374,155 +4353,9 @@
 
     /**
      * This is our own debug handler for the IMAP connection
-     * @access public
      */
     public function debug_handler(&$imap, $message)
     {
         rcube::write_log('imap', $message);
-    }
-
-
-    /**
-     * Deprecated methods (to be removed)
-     */
-
-    public function decode_address_list($input, $max = null, $decode = true, $fallback = null)
-    {
-        return rcube_mime::decode_address_list($input, $max, $decode, $fallback);
-    }
-
-    public function decode_header($input, $fallback = null)
-    {
-        return rcube_mime::decode_mime_string((string)$input, $fallback);
-    }
-
-    public static function decode_mime_string($input, $fallback = null)
-    {
-        return rcube_mime::decode_mime_string($input, $fallback);
-    }
-
-    public function mime_decode($input, $encoding = '7bit')
-    {
-        return rcube_mime::decode($input, $encoding);
-    }
-
-    public static function explode_header_string($separator, $str, $remove_comments = false)
-    {
-        return rcube_mime::explode_header_string($separator, $str, $remove_comments);
-    }
-
-    public function select_mailbox($mailbox)
-    {
-        // do nothing
-    }
-
-    public function set_mailbox($folder)
-    {
-        $this->set_folder($folder);
-    }
-
-    public function get_mailbox_name()
-    {
-        return $this->get_folder();
-    }
-
-    public function list_headers($folder='', $page=NULL, $sort_field=NULL, $sort_order=NULL, $slice=0)
-    {
-        return $this->list_messages($folder, $page, $sort_field, $sort_order, $slice);
-    }
-
-    public function get_headers($uid, $folder = null, $force = false)
-    {
-        return $this->get_message_headers($uid, $folder, $force);
-    }
-
-    public function mailbox_status($folder = null)
-    {
-        return $this->folder_status($folder);
-    }
-
-    public function message_index($folder = '', $sort_field = NULL, $sort_order = NULL)
-    {
-        return $this->index($folder, $sort_field, $sort_order);
-    }
-
-    public function message_index_direct($folder, $sort_field = null, $sort_order = null)
-    {
-        return $this->index_direct($folder, $sort_field, $sort_order);
-    }
-
-    public function list_mailboxes($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
-    {
-        return $this->list_folders_subscribed($root, $name, $filter, $rights, $skip_sort);
-    }
-
-    public function list_unsubscribed($root='', $name='*', $filter=null, $rights=null, $skip_sort=false)
-    {
-        return $this->list_folders($root, $name, $filter, $rights, $skip_sort);
-    }
-
-    public function get_mailbox_size($folder)
-    {
-        return $this->folder_size($folder);
-    }
-
-    public function create_mailbox($folder, $subscribe=false)
-    {
-        return $this->create_folder($folder, $subscribe);
-    }
-
-    public function rename_mailbox($folder, $new_name)
-    {
-        return $this->rename_folder($folder, $new_name);
-    }
-
-    function delete_mailbox($folder)
-    {
-        return $this->delete_folder($folder);
-    }
-
-    function clear_mailbox($folder = null)
-    {
-        return $this->clear_folder($folder);
-    }
-
-    public function mailbox_exists($folder, $subscription=false)
-    {
-        return $this->folder_exists($folder, $subscription);
-    }
-
-    public function mailbox_namespace($folder)
-    {
-        return $this->folder_namespace($folder);
-    }
-
-    public function mod_mailbox($folder, $mode = 'out')
-    {
-        return $this->mod_folder($folder, $mode);
-    }
-
-    public function mailbox_attributes($folder, $force = false)
-    {
-        return $this->folder_attributes($folder, $force);
-    }
-
-    public function mailbox_data($folder)
-    {
-        return $this->folder_data($folder);
-    }
-
-    public function mailbox_info($folder)
-    {
-        return $this->folder_info($folder);
-    }
-
-    public function mailbox_sync($folder)
-    {
-        return $this->folder_sync($folder);
-    }
-
-    public function expunge($folder = '', $clear_cache = true)
-    {
-        return $this->expunge_folder($folder, $clear_cache);
     }
 }

--
Gitblit v1.9.1