aboutsummaryrefslogtreecommitdiff
path: root/mail/roundcube/files/patch-program_lib_Roundcube_rcube_session.php
blob: 371c97f6ccfa04acb578a0987a3204a7845e857c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
--- program/lib/Roundcube/rcube_session.php.orig	2015-09-22 15:24:26.400132239 +0000
+++ program/lib/Roundcube/rcube_session.php	2015-09-22 15:24:08.430133455 +0000
@@ -35,7 +35,6 @@
     private $time_diff = 0;
     private $reloaded = false;
     private $appends = array();
-    private $unsets = array();
     private $gc_handlers = array();
     private $cookiename = 'roundcube_sessauth';
     private $vars;
@@ -46,6 +45,7 @@
     private $logging = false;
     private $storage;
     private $memcache;
+    private $need_base64 = false;
 
     /**
      * Blocks session data from being written to database.
@@ -95,6 +95,9 @@
         else if ($this->storage != 'php') {
             ini_set('session.serialize_handler', 'php');
 
+            if (ini_get("suhosin.session.encrypt") !== "1")
+                $this->need_base64 = true;
+
             // set custom functions for PHP session management
             session_set_save_handler(
                 array($this, 'open'),
@@ -192,7 +195,7 @@
             $this->time_diff = time() - strtotime($sql_arr['ts']);
             $this->changed   = strtotime($sql_arr['changed']);
             $this->ip        = $sql_arr['ip'];
-            $this->vars      = base64_decode($sql_arr['vars']);
+            $this->vars      = $this->_decode($sql_arr['vars']);
             $this->key       = $key;
 
             return !empty($this->vars) ? (string) $this->vars : '';
@@ -232,12 +235,12 @@
         }
 
         if ($oldvars !== null) {
-            $newvars = $this->_fixvars($vars, $oldvars);
+            $newvars = $vars;
 
             if ($newvars !== $oldvars) {
                 $this->db->query("UPDATE {$this->table_name} "
                     . "SET `changed` = $now, `vars` = ? WHERE `sess_id` = ?",
-                    base64_encode($newvars), $key);
+                    $this->_encode($newvars), $key);
             }
             else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
                 $this->db->query("UPDATE {$this->table_name} SET `changed` = $now"
@@ -248,44 +251,30 @@
             $this->db->query("INSERT INTO {$this->table_name}"
                 . " (`sess_id`, `vars`, `ip`, `created`, `changed`)"
                 . " VALUES (?, ?, ?, $now, $now)",
-                $key, base64_encode($vars), (string)$this->ip);
+                $key, $this->_encode($vars), (string)$this->ip);
         }
 
         return true;
     }
 
 
-    /**
-     * Merge vars with old vars and apply unsets
-     */
-    private function _fixvars($vars, $oldvars)
+    private function _encode($vars)
     {
-        if ($oldvars !== null) {
-            $a_oldvars = $this->unserialize($oldvars);
-            if (is_array($a_oldvars)) {
-                // remove unset keys on oldvars
-                foreach ((array)$this->unsets as $var) {
-                    if (isset($a_oldvars[$var])) {
-                        unset($a_oldvars[$var]);
-                    }
-                    else {
-                        $path = explode('.', $var);
-                        $k = array_pop($path);
-                        $node = &$this->get_node($path, $a_oldvars);
-                        unset($node[$k]);
-                    }
-                }
-
-                $newvars = $this->serialize(array_merge(
-                    (array)$a_oldvars, (array)$this->unserialize($vars)));
-            }
-            else {
-                $newvars = $vars;
-            }
+        if ($this->need_base64) {
+            return base64_encode($vars);
+        } else {
+            return $vars;
         }
+    }
 
-        $this->unsets = array();
-        return $newvars;
+
+    private function _decode($vars) 
+    {
+        if ($this->need_base64) {
+            return base64_decode($vars);
+        } else {
+            return $vars;
+        }
     }
 
 
@@ -350,7 +339,7 @@
         else // else read data again
             $oldvars = $this->mc_read($key);
 
-        $newvars = $oldvars !== null ? $this->_fixvars($vars, $oldvars) : $vars;
+        $newvars = $vars;
 
         if ($newvars !== $oldvars || $ts - $this->changed > $this->lifetime / 3) {
             return $this->memcache->set($key, serialize(array('changed' => time(), 'ip' => $this->ip, 'vars' => $newvars)),
@@ -488,8 +477,6 @@
             return $this->destroy(session_id());
         }
 
-        $this->unsets[] = $var;
-
         if (isset($_SESSION[$var])) {
             unset($_SESSION[$var]);
         }