source: subversion/trunk/roundcubemail/program/include/session.inc @ 521

Last change on this file since 521 was 521, checked in by thomasb, 6 years ago

New session authentication, should fix bugs #1483951 and #1484299; testing required

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.7 KB
Line 
1<?php
2
3/*
4 +-----------------------------------------------------------------------+
5 | program/include/session.inc                                           |
6 |                                                                       |
7 | This file is part of the RoundCube Webmail client                     |
8 | Copyright (C) 2005, RoundCube Dev, - Switzerland                      |
9 | Licensed under the GNU GPL                                            |
10 |                                                                       |
11 | PURPOSE:                                                              |
12 |   Provide database supported session management                       |
13 |                                                                       |
14 +-----------------------------------------------------------------------+
15 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16 +-----------------------------------------------------------------------+
17
18 $Id$
19
20*/
21
22
23function sess_open($save_path, $session_name)
24  {
25  return TRUE;
26  }
27
28
29
30function sess_close()
31  {
32  return TRUE;
33  }
34
35
36// read session data
37function sess_read($key)
38  {
39  global $DB, $SESS_CHANGED, $SESS_CLIENT_IP;
40 
41  if ($DB->is_error())
42    return FALSE;
43 
44  $sql_result = $DB->query("SELECT vars, ip, ".$DB->unixtimestamp('changed')." AS changed
45                            FROM ".get_table_name('session')."
46                            WHERE  sess_id=?",
47                            $key);
48
49  if ($sql_arr = $DB->fetch_assoc($sql_result))
50    {
51    $SESS_CHANGED = $sql_arr['changed'];
52    $SESS_CLIENT_IP = $sql_arr['ip'];
53
54    if (strlen($sql_arr['vars']))
55      return $sql_arr['vars'];
56    }
57
58  return FALSE;
59  }
60 
61
62// save session data
63function sess_write($key, $vars)
64  {
65  global $DB;
66 
67  if ($DB->is_error())
68    return FALSE;
69
70  $sql_result = $DB->query("SELECT 1
71                            FROM ".get_table_name('session')."
72                            WHERE  sess_id=?",
73                            $key);
74
75  if ($DB->num_rows($sql_result))
76    {
77    session_decode($vars);
78    $DB->query("UPDATE ".get_table_name('session')."
79                SET    vars=?,
80                       changed=".$DB->now()."
81                WHERE  sess_id=?",
82                $vars,
83                $key);
84    }
85  else
86    {
87    $DB->query("INSERT INTO ".get_table_name('session')."
88                (sess_id, vars, ip, created, changed)
89                VALUES (?, ?, ?, ".$DB->now().", ".$DB->now().")",
90                $key,
91                $vars,
92                $_SERVER['REMOTE_ADDR']);
93               
94
95    }
96
97  return TRUE;
98  }
99
100
101// handler for session_destroy()
102function sess_destroy($key)
103  {
104  global $DB;
105 
106  if ($DB->is_error())
107    return FALSE;
108 
109  // delete session entries in cache table
110  $DB->query("DELETE FROM ".get_table_name('cache')."
111              WHERE  session_id=?",
112              $key);
113             
114  $DB->query("DELETE FROM ".get_table_name('session')."
115              WHERE sess_id=?",
116              $key);
117
118  return TRUE;
119  }
120
121
122// garbage collecting function
123function sess_gc($maxlifetime)
124  {
125  global $DB;
126
127  if ($DB->is_error())
128    return FALSE;
129
130  // get all expired sessions 
131  $sql_result = $DB->query("SELECT sess_id
132                            FROM ".get_table_name('session')."
133                            WHERE ".$DB->unixtimestamp($DB->now())."-".$DB->unixtimestamp('changed')." > ?",
134                            $maxlifetime);
135                                   
136  $a_exp_sessions = array();
137  while ($sql_arr = $DB->fetch_assoc($sql_result))
138    $a_exp_sessions[] = $sql_arr['sess_id'];
139
140 
141  if (sizeof($a_exp_sessions))
142    {
143    // delete session cache records
144    $DB->query("DELETE FROM ".get_table_name('cache')."
145                WHERE  session_id IN ('".join("','", $a_exp_sessions)."')");
146               
147    // delete session records
148    $DB->query("DELETE FROM ".get_table_name('session')."
149                WHERE sess_id IN ('".join("','", $a_exp_sessions)."')");
150    }
151
152  // also run message cache GC
153  rcmail_message_cache_gc();
154  rcmail_temp_gc();
155
156  return TRUE;
157  }
158
159
160function sess_regenerate_id()
161  {
162  $randlen = 32;
163  $randval = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
164  $random = "";
165  for ($i=1; $i <= $randlen; $i++)
166    $random .= substr($randval, rand(0,(strlen($randval) - 1)), 1);
167
168  // use md5 value for id or remove capitals from string $randval
169  $random = md5($random);
170
171  // delete old session record
172  sess_destroy(session_id());
173
174  session_id($random);
175  $cookie = session_get_cookie_params();
176  setcookie(session_name(), $random, $cookie['lifetime'], $cookie['path']);
177
178  return true;
179  }
180
181
182// set custom functions for PHP session management
183session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy', 'sess_gc');
184
185?>
Note: See TracBrowser for help on using the repository browser.