]>
git.immae.eu Git - github/wallabag/wallabag.git/blob - inc/3rdparty/Session.class.php
3 * Session management class
5 * http://www.developpez.net/forums/d51943/php/langage/sessions/
6 * http://sebsauvage.net/wiki/doku.php?id=php:session
7 * http://sebsauvage.net/wiki/doku.php?id=php:shaarli
10 * - Everything is stored on server-side (we do not trust client-side data,
11 * such as cookie expiration)
12 * - IP addresses are checked on each access to prevent session cookie hijacking
14 * - Session expires on user inactivity (Session expiration date is
15 * automatically updated everytime the user accesses a page.)
16 * - A unique secret key is generated on server-side for this session
17 * (and never sent over the wire) which can be used to sign forms (HMAC)
18 * (See $_SESSION['uid'])
19 * - Token management to prevent XSRF attacks
20 * - Brute force protection with ban management
23 * - Replace globals with variables in Session class
26 * - http://tontof.net/kriss/php5/session
30 // Personnalize PHP session name
31 public static $sessionName = '';
32 // If the user does not access any page within this time,
33 // his/her session is considered expired (3600 sec. = 1 hour)
34 public static $inactivityTimeout = 3600;
35 // If you get disconnected often or if your IP address changes often.
36 // Let you disable session cookie hijacking protection
37 public static $disableSessionProtection = false;
38 // Ban IP after this many failures.
39 public static $banAfter = 4;
40 // Ban duration for IP address after login failures (in seconds).
41 // (1800 sec. = 30 minutes)
42 public static $banDuration = 1800;
43 // File storage for failures and bans. If empty, no ban management.
44 public static $banFile = '';
49 public static function init()
51 // Force cookie path (but do not change lifetime)
52 $cookie = session_get_cookie_params();
53 // Default cookie expiration and path.
55 if (dirname($_SERVER['SCRIPT_NAME'])!='/') {
56 $cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/';
59 if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {
62 session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['HTTP_HOST'], $ssl);
63 // Use cookies to store session.
64 ini_set('session.use_cookies', 1);
65 // Force cookies for session (phpsessionID forbidden in URL)
66 ini_set('session.use_only_cookies', 1);
68 // Prevent php to use sessionID in URL if cookies are disabled.
69 ini_set('session.use_trans_sid', false);
70 if (!empty(self
::$sessionName)) {
71 session_name(self
::$sessionName);
78 * Returns the IP address
79 * (Used to prevent session cookie hijacking.)
81 * @return string IP addresses
83 private static function _allIPs()
85 $ip = $_SERVER["REMOTE_ADDR"];
86 $ip.= isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? '_'.$_SERVER['HTTP_X_FORWARDED_FOR'] : '';
87 $ip.= isset($_SERVER['HTTP_CLIENT_IP']) ? '_'.$_SERVER['HTTP_CLIENT_IP'] : '';
93 * Check that user/password is correct and then init some SESSION variables.
95 * @param string $login Login reference
96 * @param string $password Password reference
97 * @param string $loginTest Login to compare with login reference
98 * @param string $passwordTest Password to compare with password reference
99 * @param array $pValues Array of variables to store in SESSION
101 * @return true|false True if login and password are correct, false
104 public static function login (
112 if (self
::banCanLogin()) {
113 if ($login === $loginTest && $password === $passwordTest) {
115 // Generate unique random number to sign forms (HMAC)
116 $_SESSION['uid'] = sha1(uniqid('', true).'_'.mt_rand());
117 $_SESSION['ip'] = self
::_allIPs();
118 $_SESSION['username'] = $login;
119 // Set session expiration.
120 $_SESSION['expires_on'] = time() + self
::$inactivityTimeout;
122 foreach ($pValues as $key => $value) {
123 $_SESSION[$key] = $value;
128 self
::banLoginFailed();
135 * Unset SESSION variable to force logout
137 public static function logout()
139 unset($_SESSION['uid'],$_SESSION['ip'],$_SESSION['expires_on'],$_SESSION['tokens'], $_SESSION['login'], $_SESSION['pass'], $_SESSION['poche_user']);
143 * Make sure user is logged in.
145 * @return true|false True if user is logged in, false otherwise
147 public static function isLogged()
149 if (!isset ($_SESSION['uid'])
150 || (self
::$disableSessionProtection === false
151 && $_SESSION['ip'] !== self
::_allIPs())
152 || time() >= $_SESSION['expires_on']) {
157 // User accessed a page : Update his/her session expiration date.
158 $_SESSION['expires_on'] = time() + self
::$inactivityTimeout;
159 if (!empty($_SESSION['longlastingsession'])) {
160 $_SESSION['expires_on'] +
= $_SESSION['longlastingsession'];
167 * Create a token, store it in SESSION and return it
169 * @param string $salt to prevent birthday attack
171 * @return string Token created
173 public static function getToken($salt = '')
175 if (!isset($_SESSION['tokens'])) {
176 $_SESSION['tokens']=array();
178 // We generate a random string and store it on the server side.
179 $rnd = sha1(uniqid('', true).'_'.mt_rand().$salt);
180 $_SESSION['tokens'][$rnd]=1;
186 * Tells if a token is ok. Using this function will destroy the token.
188 * @param string $token Token to test
190 * @return true|false True if token is correct, false otherwise
192 public static function isToken($token)
194 if (isset($_SESSION['tokens'][$token])) {
195 unset($_SESSION['tokens'][$token]); // Token is used: destroy it.
197 return true; // Token is ok.
200 return false; // Wrong token, or already used.
204 * Signal a failed login. Will ban the IP if too many failures:
206 public static function banLoginFailed()
208 if (self
::$banFile !== '') {
209 $ip = $_SERVER["REMOTE_ADDR"];
210 $gb = $GLOBALS['IPBANS'];
212 if (!isset($gb['FAILURES'][$ip])) {
213 $gb['FAILURES'][$ip] = 0;
215 $gb['FAILURES'][$ip]++
;
216 if ($gb['FAILURES'][$ip] > (self
::$banAfter - 1)) {
217 $gb['BANS'][$ip]= time() + self
::$banDuration;
220 $GLOBALS['IPBANS'] = $gb;
221 file_put_contents(self
::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
226 * Signals a successful login. Resets failed login counter.
228 public static function banLoginOk()
230 if (self
::$banFile !== '') {
231 $ip = $_SERVER["REMOTE_ADDR"];
232 $gb = $GLOBALS['IPBANS'];
233 unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]);
234 $GLOBALS['IPBANS'] = $gb;
235 file_put_contents(self
::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
242 public static function banInit()
244 if (self
::$banFile !== '') {
245 if (!is_file(self
::$banFile)) {
246 file_put_contents(self
::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export(array('FAILURES'=>array(), 'BANS'=>array()), true).";\n?>");
248 include self
::$banFile;
253 * Checks if the user CAN login. If 'true', the user can try to login.
255 * @return boolean true if user is banned, false otherwise
257 public static function banCanLogin()
259 if (self
::$banFile !== '') {
260 $ip = $_SERVER["REMOTE_ADDR"];
261 $gb = $GLOBALS['IPBANS'];
262 if (isset($gb['BANS'][$ip])) {
263 // User is banned. Check if the ban has expired:
264 if ($gb['BANS'][$ip] <= time()) {
265 // Ban expired, user can try to login again.
266 unset($gb['FAILURES'][$ip]);
267 unset($gb['BANS'][$ip]);
268 file_put_contents(self
::$banFile, "<?php\n\$GLOBALS['IPBANS']=".var_export($gb, true).";\n?>");
270 return true; // Ban has expired, user can login.
273 return false; // User is banned.
277 return true; // User is not banned.