]>
Commit | Line | Data |
---|---|---|
1 | <?php | |
2 | namespace Shaarli; | |
3 | ||
4 | /** | |
5 | * Manages the server-side session | |
6 | */ | |
7 | class SessionManager | |
8 | { | |
9 | /** Session expiration timeout, in seconds */ | |
10 | public static $INACTIVITY_TIMEOUT = 3600; | |
11 | ||
12 | /** Name of the cookie set after logging in **/ | |
13 | public static $LOGGED_IN_COOKIE = 'shaarli_staySignedIn'; | |
14 | ||
15 | /** Local reference to the global $_SESSION array */ | |
16 | protected $session = []; | |
17 | ||
18 | /** ConfigManager instance **/ | |
19 | protected $conf = null; | |
20 | ||
21 | /** | |
22 | * Constructor | |
23 | * | |
24 | * @param array $session The $_SESSION array (reference) | |
25 | * @param ConfigManager $conf ConfigManager instance | |
26 | */ | |
27 | public function __construct(& $session, $conf) | |
28 | { | |
29 | $this->session = &$session; | |
30 | $this->conf = $conf; | |
31 | } | |
32 | ||
33 | /** | |
34 | * Generates a session token | |
35 | * | |
36 | * @return string token | |
37 | */ | |
38 | public function generateToken() | |
39 | { | |
40 | $token = sha1(uniqid('', true) .'_'. mt_rand() . $this->conf->get('credentials.salt')); | |
41 | $this->session['tokens'][$token] = 1; | |
42 | return $token; | |
43 | } | |
44 | ||
45 | /** | |
46 | * Checks the validity of a session token, and destroys it afterwards | |
47 | * | |
48 | * @param string $token The token to check | |
49 | * | |
50 | * @return bool true if the token is valid, else false | |
51 | */ | |
52 | public function checkToken($token) | |
53 | { | |
54 | if (! isset($this->session['tokens'][$token])) { | |
55 | // the token is wrong, or has already been used | |
56 | return false; | |
57 | } | |
58 | ||
59 | // destroy the token to prevent future use | |
60 | unset($this->session['tokens'][$token]); | |
61 | return true; | |
62 | } | |
63 | ||
64 | /** | |
65 | * Validate session ID to prevent Full Path Disclosure. | |
66 | * | |
67 | * See #298. | |
68 | * The session ID's format depends on the hash algorithm set in PHP settings | |
69 | * | |
70 | * @param string $sessionId Session ID | |
71 | * | |
72 | * @return true if valid, false otherwise. | |
73 | * | |
74 | * @see http://php.net/manual/en/function.hash-algos.php | |
75 | * @see http://php.net/manual/en/session.configuration.php | |
76 | */ | |
77 | public static function checkId($sessionId) | |
78 | { | |
79 | if (empty($sessionId)) { | |
80 | return false; | |
81 | } | |
82 | ||
83 | if (!$sessionId) { | |
84 | return false; | |
85 | } | |
86 | ||
87 | if (!preg_match('/^[a-zA-Z0-9,-]{2,128}$/', $sessionId)) { | |
88 | return false; | |
89 | } | |
90 | ||
91 | return true; | |
92 | } | |
93 | ||
94 | /** | |
95 | * Store user login information after a successful login | |
96 | * | |
97 | * @param array $server The global $_SERVER array | |
98 | */ | |
99 | public function storeLoginInfo($server) | |
100 | { | |
101 | // Generate unique random number (different than phpsessionid) | |
102 | $this->session['uid'] = sha1(uniqid('', true) . '_' . mt_rand()); | |
103 | $this->session['ip'] = client_ip_id($server); | |
104 | $this->session['username'] = $this->conf->get('credentials.login'); | |
105 | $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT; | |
106 | } | |
107 | ||
108 | /** | |
109 | * Logout a user by unsetting all login information | |
110 | * | |
111 | * See: | |
112 | * - https://secure.php.net/manual/en/function.setcookie.php | |
113 | * | |
114 | * @param string $webPath path on the server in which the cookie will be available on | |
115 | */ | |
116 | public function logout($webPath) | |
117 | { | |
118 | if (isset($this->session)) { | |
119 | unset($this->session['uid']); | |
120 | unset($this->session['ip']); | |
121 | unset($this->session['username']); | |
122 | unset($this->session['visibility']); | |
123 | unset($this->session['untaggedonly']); | |
124 | } | |
125 | setcookie(self::$LOGGED_IN_COOKIE, 'false', 0, $webPath); | |
126 | } | |
127 | } |