View | Details | Raw Unified | Return to bug 203260
Collapse All | Expand All

(-)program/lib/Roundcube/rcube_session.php (-36 / +23 lines)
Lines 35-41 Link Here
35
    private $time_diff = 0;
35
    private $time_diff = 0;
36
    private $reloaded = false;
36
    private $reloaded = false;
37
    private $appends = array();
37
    private $appends = array();
38
    private $unsets = array();
39
    private $gc_handlers = array();
38
    private $gc_handlers = array();
40
    private $cookiename = 'roundcube_sessauth';
39
    private $cookiename = 'roundcube_sessauth';
41
    private $vars;
40
    private $vars;
Lines 46-51 Link Here
46
    private $logging = false;
45
    private $logging = false;
47
    private $storage;
46
    private $storage;
48
    private $memcache;
47
    private $memcache;
48
    private $need_base64 = false;
49
49
50
    /**
50
    /**
51
     * Blocks session data from being written to database.
51
     * Blocks session data from being written to database.
Lines 95-100 Link Here
95
        else if ($this->storage != 'php') {
95
        else if ($this->storage != 'php') {
96
            ini_set('session.serialize_handler', 'php');
96
            ini_set('session.serialize_handler', 'php');
97
97
98
            if (ini_get("suhosin.session.encrypt") !== "1")
99
                $this->need_base64 = true;
100
98
            // set custom functions for PHP session management
101
            // set custom functions for PHP session management
99
            session_set_save_handler(
102
            session_set_save_handler(
100
                array($this, 'open'),
103
                array($this, 'open'),
Lines 192-198 Link Here
192
            $this->time_diff = time() - strtotime($sql_arr['ts']);
195
            $this->time_diff = time() - strtotime($sql_arr['ts']);
193
            $this->changed   = strtotime($sql_arr['changed']);
196
            $this->changed   = strtotime($sql_arr['changed']);
194
            $this->ip        = $sql_arr['ip'];
197
            $this->ip        = $sql_arr['ip'];
195
            $this->vars      = base64_decode($sql_arr['vars']);
198
            $this->vars      = $this->_decode($sql_arr['vars']);
196
            $this->key       = $key;
199
            $this->key       = $key;
197
200
198
            return !empty($this->vars) ? (string) $this->vars : '';
201
            return !empty($this->vars) ? (string) $this->vars : '';
Lines 232-243 Link Here
232
        }
235
        }
233
236
234
        if ($oldvars !== null) {
237
        if ($oldvars !== null) {
235
            $newvars = $this->_fixvars($vars, $oldvars);
238
            $newvars = $vars;
236
239
237
            if ($newvars !== $oldvars) {
240
            if ($newvars !== $oldvars) {
238
                $this->db->query("UPDATE {$this->table_name} "
241
                $this->db->query("UPDATE {$this->table_name} "
239
                    . "SET `changed` = $now, `vars` = ? WHERE `sess_id` = ?",
242
                    . "SET `changed` = $now, `vars` = ? WHERE `sess_id` = ?",
240
                    base64_encode($newvars), $key);
243
                    $this->_encode($newvars), $key);
241
            }
244
            }
242
            else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
245
            else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
243
                $this->db->query("UPDATE {$this->table_name} SET `changed` = $now"
246
                $this->db->query("UPDATE {$this->table_name} SET `changed` = $now"
Lines 248-291 Link Here
248
            $this->db->query("INSERT INTO {$this->table_name}"
251
            $this->db->query("INSERT INTO {$this->table_name}"
249
                . " (`sess_id`, `vars`, `ip`, `created`, `changed`)"
252
                . " (`sess_id`, `vars`, `ip`, `created`, `changed`)"
250
                . " VALUES (?, ?, ?, $now, $now)",
253
                . " VALUES (?, ?, ?, $now, $now)",
251
                $key, base64_encode($vars), (string)$this->ip);
254
                $key, $this->_encode($vars), (string)$this->ip);
252
        }
255
        }
253
256
254
        return true;
257
        return true;
255
    }
258
    }
256
259
257
260
258
    /**
261
    private function _encode($vars)
259
     * Merge vars with old vars and apply unsets
260
     */
261
    private function _fixvars($vars, $oldvars)
262
    {
262
    {
263
        if ($oldvars !== null) {
263
        if ($this->need_base64) {
264
            $a_oldvars = $this->unserialize($oldvars);
264
            return base64_encode($vars);
265
            if (is_array($a_oldvars)) {
265
        } else {
266
                // remove unset keys on oldvars
266
            return $vars;
267
                foreach ((array)$this->unsets as $var) {
268
                    if (isset($a_oldvars[$var])) {
269
                        unset($a_oldvars[$var]);
270
                    }
271
                    else {
272
                        $path = explode('.', $var);
273
                        $k = array_pop($path);
274
                        $node = &$this->get_node($path, $a_oldvars);
275
                        unset($node[$k]);
276
                    }
277
                }
278
279
                $newvars = $this->serialize(array_merge(
280
                    (array)$a_oldvars, (array)$this->unserialize($vars)));
281
            }
282
            else {
283
                $newvars = $vars;
284
            }
285
        }
267
        }
268
    }
286
269
287
        $this->unsets = array();
270
288
        return $newvars;
271
    private function _decode($vars) 
272
    {
273
        if ($this->need_base64) {
274
            return base64_decode($vars);
275
        } else {
276
            return $vars;
277
        }
289
    }
278
    }
290
279
291
280
Lines 350-356 Link Here
350
        else // else read data again
339
        else // else read data again
351
            $oldvars = $this->mc_read($key);
340
            $oldvars = $this->mc_read($key);
352
341
353
        $newvars = $oldvars !== null ? $this->_fixvars($vars, $oldvars) : $vars;
342
        $newvars = $vars;
354
343
355
        if ($newvars !== $oldvars || $ts - $this->changed > $this->lifetime / 3) {
344
        if ($newvars !== $oldvars || $ts - $this->changed > $this->lifetime / 3) {
356
            return $this->memcache->set($key, serialize(array('changed' => time(), 'ip' => $this->ip, 'vars' => $newvars)),
345
            return $this->memcache->set($key, serialize(array('changed' => time(), 'ip' => $this->ip, 'vars' => $newvars)),
Lines 488-495 Link Here
488
            return $this->destroy(session_id());
477
            return $this->destroy(session_id());
489
        }
478
        }
490
479
491
        $this->unsets[] = $var;
492
493
        if (isset($_SESSION[$var])) {
480
        if (isset($_SESSION[$var])) {
494
            unset($_SESSION[$var]);
481
            unset($_SESSION[$var]);
495
        }
482
        }

Return to bug 203260