443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
1 |
<?php
|
2 |
/**
|
|
3 |
*
|
|
4 |
* @package phpBB3
|
|
5 |
* @version $Id: session.php,v 1.317 2007/11/04 12:07:46 acydburn Exp $
|
|
6 |
* @copyright (c) 2005 phpBB Group
|
|
7 |
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
8 |
*
|
|
9 |
*/
|
|
10 |
||
11 |
/**
|
|
12 |
* @ignore
|
|
13 |
*/
|
|
14 |
if (!defined('IN_PHPBB')) |
|
15 |
{
|
|
16 |
exit; |
|
17 |
}
|
|
18 |
||
19 |
/**
|
|
20 |
* Session class
|
|
21 |
* @package phpBB3
|
|
22 |
*/
|
|
23 |
class session |
|
24 |
{
|
|
25 |
var $cookie_data = array(); |
|
26 |
var $page = array(); |
|
27 |
var $data = array(); |
|
28 |
var $browser = ''; |
|
29 |
var $forwarded_for = ''; |
|
30 |
var $host = ''; |
|
31 |
var $session_id = ''; |
|
32 |
var $ip = ''; |
|
33 |
var $load = 0; |
|
34 |
var $time_now = 0; |
|
35 |
var $update_session_page = true; |
|
36 |
||
37 |
/**
|
|
38 |
* Extract current session page
|
|
39 |
*
|
|
40 |
* @param string $root_path current root path (phpbb_root_path)
|
|
41 |
*/
|
|
42 |
function extract_current_page($root_path) |
|
43 |
{
|
|
44 |
$page_array = array(); |
|
45 |
||
46 |
// First of all, get the request uri...
|
|
47 |
$script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF'); |
|
48 |
$args = (!empty($_SERVER['QUERY_STRING'])) ? explode('&', $_SERVER['QUERY_STRING']) : explode('&', getenv('QUERY_STRING')); |
|
49 |
||
50 |
// If we are unable to get the script name we use REQUEST_URI as a failover and note it within the page array for easier support...
|
|
51 |
if (!$script_name) |
|
52 |
{
|
|
53 |
$script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI'); |
|
54 |
$script_name = (($pos = strpos($script_name, '?')) !== false) ? substr($script_name, 0, $pos) : $script_name; |
|
55 |
$page_array['failover'] = 1; |
|
56 |
}
|
|
57 |
||
58 |
// Replace backslashes and doubled slashes (could happen on some proxy setups)
|
|
59 |
$script_name = str_replace(array('\\', '//'), '/', $script_name); |
|
60 |
||
61 |
// Now, remove the sid and let us get a clean query string...
|
|
62 |
$use_args = array(); |
|
63 |
||
64 |
// Since some browser do not encode correctly we need to do this with some "special" characters...
|
|
65 |
// " -> %22, ' => %27, < -> %3C, > -> %3E
|
|
66 |
$find = array('"', "'", '<', '>'); |
|
67 |
$replace = array('%22', '%27', '%3C', '%3E'); |
|
68 |
||
69 |
foreach ($args as $key => $argument) |
|
70 |
{
|
|
71 |
if (strpos($argument, 'sid=') === 0 || strpos($argument, '_f_=') === 0) |
|
72 |
{
|
|
73 |
continue; |
|
74 |
}
|
|
75 |
||
76 |
$use_args[str_replace($find, $replace, $key)] = str_replace($find, $replace, $argument); |
|
77 |
}
|
|
78 |
unset($args); |
|
79 |
||
80 |
// The following examples given are for an request uri of {path to the phpbb directory}/adm/index.php?i=10&b=2
|
|
81 |
||
82 |
// The current query string
|
|
83 |
$query_string = trim(implode('&', $use_args)); |
|
84 |
||
85 |
// basenamed page name (for example: index.php)
|
|
86 |
$page_name = basename($script_name); |
|
87 |
$page_name = urlencode(htmlspecialchars($page_name)); |
|
88 |
||
89 |
// current directory within the phpBB root (for example: adm)
|
|
90 |
$root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($root_path))); |
|
91 |
$page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath('./'))); |
|
92 |
$intersection = array_intersect_assoc($root_dirs, $page_dirs); |
|
93 |
||
94 |
$root_dirs = array_diff_assoc($root_dirs, $intersection); |
|
95 |
$page_dirs = array_diff_assoc($page_dirs, $intersection); |
|
96 |
||
97 |
$page_dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs); |
|
98 |
||
99 |
if ($page_dir && substr($page_dir, -1, 1) == '/') |
|
100 |
{
|
|
101 |
$page_dir = substr($page_dir, 0, -1); |
|
102 |
}
|
|
103 |
||
104 |
// Current page from phpBB root (for example: adm/index.php?i=10&b=2)
|
|
105 |
$page = (($page_dir) ? $page_dir . '/' : '') . $page_name . (($query_string) ? "?$query_string" : ''); |
|
106 |
||
107 |
// The script path from the webroot to the current directory (for example: /phpBB3/adm/) : always prefixed with / and ends in /
|
|
108 |
$script_path = trim(str_replace('\\', '/', dirname($script_name))); |
|
109 |
||
110 |
// The script path from the webroot to the phpBB root (for example: /phpBB3/)
|
|
111 |
$script_dirs = explode('/', $script_path); |
|
112 |
array_splice($script_dirs, -sizeof($page_dirs)); |
|
113 |
$root_script_path = implode('/', $script_dirs) . (sizeof($root_dirs) ? '/' . implode('/', $root_dirs) : ''); |
|
114 |
||
115 |
// We are on the base level (phpBB root == webroot), lets adjust the variables a bit...
|
|
116 |
if (!$root_script_path) |
|
117 |
{
|
|
118 |
$root_script_path = ($page_dir) ? str_replace($page_dir, '', $script_path) : $script_path; |
|
119 |
}
|
|
120 |
||
121 |
$script_path .= (substr($script_path, -1, 1) == '/') ? '' : '/'; |
|
122 |
$root_script_path .= (substr($root_script_path, -1, 1) == '/') ? '' : '/'; |
|
123 |
||
124 |
$page_array += array( |
|
125 |
'page_name' => $page_name, |
|
126 |
'page_dir' => $page_dir, |
|
127 |
||
128 |
'query_string' => $query_string, |
|
129 |
'script_path' => str_replace(' ', '%20', htmlspecialchars($script_path)), |
|
130 |
'root_script_path' => str_replace(' ', '%20', htmlspecialchars($root_script_path)), |
|
131 |
||
132 |
'page' => $page |
|
133 |
);
|
|
134 |
||
135 |
return $page_array; |
|
136 |
}
|
|
137 |
||
138 |
/**
|
|
139 |
* Start session management
|
|
140 |
*
|
|
141 |
* This is where all session activity begins. We gather various pieces of
|
|
142 |
* information from the client and server. We test to see if a session already
|
|
143 |
* exists. If it does, fine and dandy. If it doesn't we'll go on to create a
|
|
144 |
* new one ... pretty logical heh? We also examine the system load (if we're
|
|
145 |
* running on a system which makes such information readily available) and
|
|
146 |
* halt if it's above an admin definable limit.
|
|
147 |
*
|
|
148 |
* @param bool $update_session_page if true the session page gets updated.
|
|
149 |
* This can be set to circumvent certain scripts to update the users last visited page.
|
|
150 |
*/
|
|
151 |
function session_begin($update_session_page = true) |
|
152 |
{
|
|
153 |
global $phpEx, $SID, $_SID, $_EXTRA_URL, $db, $config, $phpbb_root_path; |
|
154 |
||
155 |
// Give us some basic information
|
|
156 |
$this->time_now = time(); |
|
157 |
$this->cookie_data = array('u' => 0, 'k' => ''); |
|
158 |
$this->update_session_page = $update_session_page; |
|
159 |
$this->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : ''; |
|
160 |
$this->forwarded_for = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : ''; |
|
161 |
$this->host = (!empty($_SERVER['HTTP_HOST'])) ? (string) $_SERVER['HTTP_HOST'] : 'localhost'; |
|
162 |
$this->page = $this->extract_current_page($phpbb_root_path); |
|
163 |
||
164 |
// if the forwarded for header shall be checked we have to validate its contents
|
|
165 |
if ($config['forwarded_for_check']) |
|
166 |
{
|
|
167 |
$this->forwarded_for = preg_replace('#, +#', ', ', $this->forwarded_for); |
|
168 |
||
169 |
// split the list of IPs
|
|
170 |
$ips = explode(', ', $this->forwarded_for); |
|
171 |
foreach ($ips as $ip) |
|
172 |
{
|
|
173 |
// check IPv4 first, the IPv6 is hopefully only going to be used very seldomly
|
|
174 |
if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) |
|
175 |
{
|
|
176 |
// contains invalid data, don't use the forwarded for header
|
|
177 |
$this->forwarded_for = ''; |
|
178 |
break; |
|
179 |
}
|
|
180 |
}
|
|
181 |
}
|
|
182 |
||
183 |
// Add forum to the page for tracking online users - also adding a "x" to the end to properly identify the number
|
|
184 |
$this->page['page'] .= (isset($_REQUEST['f'])) ? ((strpos($this->page['page'], '?') !== false) ? '&' : '?') . '_f_=' . (int) $_REQUEST['f'] . 'x' : ''; |
|
185 |
||
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
186 |
|
187 |
if (isset($_COOKIE[$config['cookie_name'] . '_sid']) || |
|
188 |
isset($_COOKIE[$config['cookie_name'] . '_u'])) |
|
189 |
{
|
|
190 |
$this->cookie_data['u'] = request_var($config['cookie_name'] . '_u', 0, |
|
191 |
false, true); |
|
192 |
$this->cookie_data['k'] = request_var($config['cookie_name'] . '_k', '', |
|
193 |
false, true); |
|
194 |
$this->session_id = request_var($config['cookie_name'] . '_sid', '', |
|
195 |
false, true); |
|
196 |
||
197 |
$SID = (defined('NEED_SID')) ? '?sid=' . $this->session_id : '?sid='; |
|
198 |
$_SID = (defined('NEED_SID')) ? $this->session_id : ''; |
|
199 |
||
200 |
if (empty($this->session_id)) |
|
201 |
{
|
|
202 |
$this->session_id = $_SID = request_var('sid', ''); |
|
203 |
$SID = '?sid=' . $this->session_id; |
|
204 |
$this->cookie_data = array('u' => 0, 'k' => ''); |
|
205 |
}
|
|
206 |
}
|
|
207 |
else
|
|
208 |
{
|
|
209 |
$this->session_id = $_SID = request_var('sid', ''); |
|
210 |
$SID = '?sid=' . $this->session_id; |
|
211 |
}
|
|
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
212 |
|
213 |
$_EXTRA_URL = array(); |
|
214 |
||
215 |
// Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests
|
|
216 |
// it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip.
|
|
217 |
$this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : ''; |
|
218 |
$this->load = false; |
|
219 |
||
220 |
// Load limit check (if applicable)
|
|
221 |
if ($config['limit_load'] || $config['limit_search_load']) |
|
222 |
{
|
|
223 |
if ($load = @file_get_contents('/proc/loadavg')) |
|
224 |
{
|
|
225 |
$this->load = array_slice(explode(' ', $load), 0, 1); |
|
226 |
$this->load = floatval($this->load[0]); |
|
227 |
}
|
|
228 |
else
|
|
229 |
{
|
|
230 |
set_config('limit_load', '0'); |
|
231 |
set_config('limit_search_load', '0'); |
|
232 |
}
|
|
233 |
}
|
|
234 |
||
235 |
// Is session_id is set or session_id is set and matches the url param if required
|
|
236 |
if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid']))) |
|
237 |
{
|
|
238 |
$sql = 'SELECT u.*, s.* |
|
239 |
FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u |
|
240 |
WHERE s.session_id = '" . $db->sql_escape($this->session_id) . "' |
|
241 |
AND u.user_id = s.session_user_id"; |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
242 |
$result = $db->sql_query($sql); |
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
243 |
$this->data = $db->sql_fetchrow($result); |
244 |
$db->sql_freeresult($result); |
|
245 |
||
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
246 |
// IVLE
|
247 |
$ivle_userid = $this->ivle_auth(); |
|
248 |
if ($ivle_userid and $ivle_userid != $this->data['user_id']) { |
|
249 |
#$this->session_kill();
|
|
250 |
#trigger_error($ivle_userid);
|
|
251 |
return $this->session_create($ivle_userid); |
|
252 |
}
|
|
253 |
||
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
254 |
// Did the session exist in the DB?
|
255 |
if (isset($this->data['user_id'])) |
|
256 |
{
|
|
257 |
// Validate IP length according to admin ... enforces an IP
|
|
258 |
// check on bots if admin requires this
|
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
259 |
// $quadcheck = ($config['ip_check_bot'] && $this->data['user_type'] & USER_BOT) ? 4 : $config['ip_check'];
|
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
260 |
|
261 |
if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false) |
|
262 |
{
|
|
263 |
$s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']); |
|
264 |
$u_ip = short_ipv6($this->ip, $config['ip_check']); |
|
265 |
}
|
|
266 |
else
|
|
267 |
{
|
|
268 |
$s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); |
|
269 |
$u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); |
|
270 |
}
|
|
271 |
||
272 |
$s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : ''; |
|
273 |
$u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : ''; |
|
274 |
||
275 |
$s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : ''; |
|
276 |
$u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : ''; |
|
277 |
||
278 |
if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for) |
|
279 |
{
|
|
280 |
$session_expired = false; |
|
281 |
||
282 |
// Check whether the session is still valid if we have one
|
|
283 |
$method = basename(trim($config['auth_method'])); |
|
284 |
include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx); |
|
285 |
||
286 |
$method = 'validate_session_' . $method; |
|
287 |
if (function_exists($method)) |
|
288 |
{
|
|
289 |
if (!$method($this->data)) |
|
290 |
{
|
|
291 |
$session_expired = true; |
|
292 |
}
|
|
293 |
}
|
|
294 |
||
295 |
if (!$session_expired) |
|
296 |
{
|
|
297 |
// Check the session length timeframe if autologin is not enabled.
|
|
298 |
// Else check the autologin length... and also removing those having autologin enabled but no longer allowed board-wide.
|
|
299 |
if (!$this->data['session_autologin']) |
|
300 |
{
|
|
301 |
if ($this->data['session_time'] < $this->time_now - ($config['session_length'] + 60)) |
|
302 |
{
|
|
303 |
$session_expired = true; |
|
304 |
}
|
|
305 |
}
|
|
306 |
else if (!$config['allow_autologin'] || ($config['max_autologin_time'] && $this->data['session_time'] < $this->time_now - (86400 * (int) $config['max_autologin_time']) + 60)) |
|
307 |
{
|
|
308 |
$session_expired = true; |
|
309 |
}
|
|
310 |
}
|
|
311 |
||
312 |
if (!$session_expired) |
|
313 |
{
|
|
314 |
// Only update session DB a minute or so after last update or if page changes
|
|
315 |
if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) |
|
316 |
{
|
|
317 |
$sql_ary = array('session_time' => $this->time_now); |
|
318 |
||
319 |
if ($this->update_session_page) |
|
320 |
{
|
|
321 |
$sql_ary['session_page'] = substr($this->page['page'], 0, 199); |
|
322 |
}
|
|
323 |
||
324 |
$sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " |
|
325 |
WHERE session_id = '" . $db->sql_escape($this->session_id) . "'"; |
|
326 |
$db->sql_query($sql); |
|
327 |
}
|
|
328 |
||
329 |
$this->data['is_registered'] = ($this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false; |
|
330 |
$this->data['is_bot'] = (!$this->data['is_registered'] && $this->data['user_id'] != ANONYMOUS) ? true : false; |
|
331 |
$this->data['user_lang'] = basename($this->data['user_lang']); |
|
332 |
||
333 |
return true; |
|
334 |
}
|
|
335 |
}
|
|
336 |
else
|
|
337 |
{
|
|
338 |
// Added logging temporarly to help debug bugs...
|
|
339 |
if (defined('DEBUG_EXTRA') && $this->data['user_id'] != ANONYMOUS) |
|
340 |
{
|
|
341 |
add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, htmlspecialchars($u_forwarded_for), htmlspecialchars($s_forwarded_for)); |
|
342 |
}
|
|
343 |
}
|
|
344 |
}
|
|
345 |
}
|
|
346 |
||
347 |
// If we reach here then no (valid) session exists. So we'll create a new one
|
|
348 |
return $this->session_create(); |
|
349 |
}
|
|
350 |
||
351 |
/**
|
|
352 |
* Create a new session
|
|
353 |
*
|
|
354 |
* If upon trying to start a session we discover there is nothing existing we
|
|
355 |
* jump here. Additionally this method is called directly during login to regenerate
|
|
356 |
* the session for the specific user. In this method we carry out a number of tasks;
|
|
357 |
* garbage collection, (search)bot checking, banned user comparison. Basically
|
|
358 |
* though this method will result in a new session for a specific user.
|
|
359 |
*/
|
|
360 |
function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true) |
|
361 |
{
|
|
362 |
global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx; |
|
363 |
||
364 |
$this->data = array(); |
|
365 |
||
366 |
/* Garbage collection ... remove old sessions updating user information
|
|
367 |
// if necessary. It means (potentially) 11 queries but only infrequently
|
|
368 |
if ($this->time_now > $config['session_last_gc'] + $config['session_gc'])
|
|
369 |
{
|
|
370 |
$this->session_gc();
|
|
371 |
}*/
|
|
461
by dcoles
Added Auth bridge between IVLE and phpBB using shared cookie |
372 |
|
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
373 |
// Do we allow autologin on this board? No? Then override anything
|
374 |
// that may be requested here
|
|
375 |
if (!$config['allow_autologin']) |
|
376 |
{
|
|
377 |
$this->cookie_data['k'] = $persist_login = false; |
|
378 |
}
|
|
379 |
||
380 |
/**
|
|
381 |
* Here we do a bot check, oh er saucy! No, not that kind of bot
|
|
382 |
* check. We loop through the list of bots defined by the admin and
|
|
383 |
* see if we have any useragent and/or IP matches. If we do, this is a
|
|
384 |
* bot, act accordingly
|
|
385 |
*/
|
|
386 |
$bot = false; |
|
387 |
$active_bots = $cache->obtain_bots(); |
|
388 |
||
389 |
foreach ($active_bots as $row) |
|
390 |
{
|
|
391 |
if ($row['bot_agent'] && preg_match('#' . str_replace('\*', '.*?', preg_quote($row['bot_agent'], '#')) . '#i', $this->browser)) |
|
392 |
{
|
|
393 |
$bot = $row['user_id']; |
|
394 |
}
|
|
395 |
||
396 |
// If ip is supplied, we will make sure the ip is matching too...
|
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
397 |
if ($row['bot_ip'] && ($bot || !$row['bot_agent'])) |
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
398 |
{
|
399 |
// Set bot to false, then we only have to set it to true if it is matching
|
|
400 |
$bot = false; |
|
401 |
||
402 |
foreach (explode(',', $row['bot_ip']) as $bot_ip) |
|
403 |
{
|
|
404 |
if (strpos($this->ip, $bot_ip) === 0) |
|
405 |
{
|
|
406 |
$bot = (int) $row['user_id']; |
|
407 |
break; |
|
408 |
}
|
|
409 |
}
|
|
410 |
}
|
|
411 |
||
412 |
if ($bot) |
|
413 |
{
|
|
414 |
break; |
|
415 |
}
|
|
416 |
}
|
|
417 |
||
418 |
$method = basename(trim($config['auth_method'])); |
|
419 |
include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx); |
|
420 |
||
421 |
$method = 'autologin_' . $method; |
|
422 |
if (function_exists($method)) |
|
423 |
{
|
|
424 |
$this->data = $method(); |
|
425 |
||
426 |
if (sizeof($this->data)) |
|
427 |
{
|
|
428 |
$this->cookie_data['k'] = ''; |
|
429 |
$this->cookie_data['u'] = $this->data['user_id']; |
|
430 |
}
|
|
431 |
}
|
|
432 |
||
433 |
// If we're presented with an autologin key we'll join against it.
|
|
434 |
// Else if we've been passed a user_id we'll grab data based on that
|
|
435 |
if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data)) |
|
436 |
{
|
|
437 |
$sql = 'SELECT u.* |
|
438 |
FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k |
|
439 |
WHERE u.user_id = ' . (int) $this->cookie_data['u'] . ' |
|
440 |
AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ") |
|
441 |
AND k.user_id = u.user_id
|
|
442 |
AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'"; |
|
443 |
$result = $db->sql_query($sql); |
|
444 |
$this->data = $db->sql_fetchrow($result); |
|
445 |
$db->sql_freeresult($result); |
|
446 |
$bot = false; |
|
447 |
}
|
|
448 |
else if ($user_id !== false && !sizeof($this->data)) |
|
449 |
{
|
|
450 |
$this->cookie_data['k'] = ''; |
|
451 |
$this->cookie_data['u'] = $user_id; |
|
452 |
||
453 |
$sql = 'SELECT * |
|
454 |
FROM ' . USERS_TABLE . ' |
|
455 |
WHERE user_id = ' . (int) $this->cookie_data['u'] . ' |
|
456 |
AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; |
|
457 |
$result = $db->sql_query($sql); |
|
458 |
$this->data = $db->sql_fetchrow($result); |
|
459 |
$db->sql_freeresult($result); |
|
460 |
$bot = false; |
|
461 |
}
|
|
462 |
||
463 |
// If no data was returned one or more of the following occurred:
|
|
464 |
// Key didn't match one in the DB
|
|
465 |
// User does not exist
|
|
466 |
// User is inactive
|
|
467 |
// User is bot
|
|
468 |
if (!sizeof($this->data) || !is_array($this->data)) |
|
469 |
{
|
|
470 |
$this->cookie_data['k'] = ''; |
|
471 |
$this->cookie_data['u'] = ($bot) ? $bot : ANONYMOUS; |
|
472 |
||
473 |
if (!$bot) |
|
474 |
{
|
|
475 |
$sql = 'SELECT * |
|
476 |
FROM ' . USERS_TABLE . ' |
|
477 |
WHERE user_id = ' . (int) $this->cookie_data['u']; |
|
478 |
}
|
|
479 |
else
|
|
480 |
{
|
|
481 |
// We give bots always the same session if it is not yet expired.
|
|
482 |
$sql = 'SELECT u.*, s.* |
|
483 |
FROM ' . USERS_TABLE . ' u |
|
484 |
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id) |
|
485 |
WHERE u.user_id = ' . (int) $bot; |
|
486 |
}
|
|
487 |
||
488 |
$result = $db->sql_query($sql); |
|
489 |
$this->data = $db->sql_fetchrow($result); |
|
490 |
$db->sql_freeresult($result); |
|
491 |
}
|
|
492 |
||
493 |
if ($this->data['user_id'] != ANONYMOUS && !$bot) |
|
494 |
{
|
|
495 |
$this->data['session_last_visit'] = (isset($this->data['session_time']) && $this->data['session_time']) ? $this->data['session_time'] : (($this->data['user_lastvisit']) ? $this->data['user_lastvisit'] : time()); |
|
496 |
}
|
|
497 |
else
|
|
498 |
{
|
|
499 |
$this->data['session_last_visit'] = $this->time_now; |
|
500 |
}
|
|
501 |
||
502 |
// Force user id to be integer...
|
|
503 |
$this->data['user_id'] = (int) $this->data['user_id']; |
|
504 |
||
505 |
// At this stage we should have a filled data array, defined cookie u and k data.
|
|
506 |
// data array should contain recent session info if we're a real user and a recent
|
|
507 |
// session exists in which case session_id will also be set
|
|
508 |
||
509 |
// Is user banned? Are they excluded? Won't return on ban, exists within method
|
|
510 |
if ($this->data['user_type'] != USER_FOUNDER) |
|
511 |
{
|
|
512 |
if (!$config['forwarded_for_check']) |
|
513 |
{
|
|
514 |
$this->check_ban($this->data['user_id'], $this->ip); |
|
515 |
}
|
|
516 |
else
|
|
517 |
{
|
|
518 |
$ips = explode(', ', $this->forwarded_for); |
|
519 |
$ips[] = $this->ip; |
|
520 |
$this->check_ban($this->data['user_id'], $ips); |
|
521 |
}
|
|
522 |
}
|
|
523 |
||
524 |
$this->data['is_registered'] = (!$bot && $this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false; |
|
525 |
$this->data['is_bot'] = ($bot) ? true : false; |
|
526 |
||
527 |
// If our friend is a bot, we re-assign a previously assigned session
|
|
528 |
if ($this->data['is_bot'] && $bot == $this->data['user_id'] && $this->data['session_id']) |
|
529 |
{
|
|
530 |
// Only assign the current session if the ip, browser and forwarded_for match...
|
|
531 |
if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false) |
|
532 |
{
|
|
533 |
$s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']); |
|
534 |
$u_ip = short_ipv6($this->ip, $config['ip_check']); |
|
535 |
}
|
|
536 |
else
|
|
537 |
{
|
|
538 |
$s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); |
|
539 |
$u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); |
|
540 |
}
|
|
541 |
||
542 |
$s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : ''; |
|
543 |
$u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : ''; |
|
544 |
||
545 |
$s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : ''; |
|
546 |
$u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : ''; |
|
547 |
||
548 |
if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for) |
|
549 |
{
|
|
550 |
$this->session_id = $this->data['session_id']; |
|
551 |
||
552 |
// Only update session DB a minute or so after last update or if page changes
|
|
553 |
if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) |
|
554 |
{
|
|
555 |
$this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now; |
|
556 |
||
557 |
$sql_ary = array('session_time' => $this->time_now, 'session_last_visit' => $this->time_now, 'session_admin' => 0); |
|
558 |
||
559 |
if ($this->update_session_page) |
|
560 |
{
|
|
561 |
$sql_ary['session_page'] = substr($this->page['page'], 0, 199); |
|
562 |
}
|
|
563 |
||
564 |
$sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " |
|
565 |
WHERE session_id = '" . $db->sql_escape($this->session_id) . "'"; |
|
566 |
$db->sql_query($sql); |
|
567 |
||
568 |
// Update the last visit time
|
|
569 |
$sql = 'UPDATE ' . USERS_TABLE . ' |
|
570 |
SET user_lastvisit = ' . (int) $this->data['session_time'] . ' |
|
571 |
WHERE user_id = ' . (int) $this->data['user_id']; |
|
572 |
$db->sql_query($sql); |
|
573 |
}
|
|
574 |
||
575 |
$SID = '?sid='; |
|
576 |
$_SID = ''; |
|
577 |
return true; |
|
578 |
}
|
|
579 |
else
|
|
580 |
{
|
|
581 |
// If the ip and browser does not match make sure we only have one bot assigned to one session
|
|
582 |
$db->sql_query('DELETE FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . $this->data['user_id']); |
|
583 |
}
|
|
584 |
}
|
|
585 |
||
586 |
$session_autologin = (($this->cookie_data['k'] || $persist_login) && $this->data['is_registered']) ? true : false; |
|
587 |
$set_admin = ($set_admin && $this->data['is_registered']) ? true : false; |
|
588 |
||
589 |
// Create or update the session
|
|
590 |
$sql_ary = array( |
|
591 |
'session_user_id' => (int) $this->data['user_id'], |
|
592 |
'session_start' => (int) $this->time_now, |
|
593 |
'session_last_visit' => (int) $this->data['session_last_visit'], |
|
594 |
'session_time' => (int) $this->time_now, |
|
595 |
'session_browser' => (string) substr($this->browser, 0, 149), |
|
596 |
'session_forwarded_for' => (string) $this->forwarded_for, |
|
597 |
'session_ip' => (string) $this->ip, |
|
598 |
'session_autologin' => ($session_autologin) ? 1 : 0, |
|
599 |
'session_admin' => ($set_admin) ? 1 : 0, |
|
600 |
'session_viewonline' => ($viewonline) ? 1 : 0, |
|
601 |
);
|
|
602 |
||
603 |
if ($this->update_session_page) |
|
604 |
{
|
|
605 |
$sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199); |
|
606 |
}
|
|
607 |
||
608 |
$db->sql_return_on_error(true); |
|
609 |
||
610 |
$sql = 'DELETE |
|
611 |
FROM ' . SESSIONS_TABLE . ' |
|
612 |
WHERE session_id = \'' . $db->sql_escape($this->session_id) . '\' |
|
613 |
AND session_user_id = ' . ANONYMOUS; |
|
614 |
||
615 |
if (!defined('IN_ERROR_HANDLER') && (!$this->session_id || !$db->sql_query($sql) || !$db->sql_affectedrows())) |
|
616 |
{
|
|
617 |
// Limit new sessions in 1 minute period (if required)
|
|
618 |
if (empty($this->data['session_time']) && $config['active_sessions']) |
|
619 |
{
|
|
620 |
$sql = 'SELECT COUNT(session_id) AS sessions |
|
621 |
FROM ' . SESSIONS_TABLE . ' |
|
622 |
WHERE session_time >= ' . ($this->time_now - 60); |
|
623 |
$result = $db->sql_query($sql); |
|
624 |
$row = $db->sql_fetchrow($result); |
|
625 |
$db->sql_freeresult($result); |
|
626 |
||
627 |
if ((int) $row['sessions'] > (int) $config['active_sessions']) |
|
628 |
{
|
|
629 |
header('HTTP/1.1 503 Service Unavailable'); |
|
630 |
trigger_error('BOARD_UNAVAILABLE'); |
|
631 |
}
|
|
632 |
}
|
|
633 |
}
|
|
634 |
||
635 |
$this->session_id = $this->data['session_id'] = md5(unique_id()); |
|
636 |
||
637 |
$sql_ary['session_id'] = (string) $this->session_id; |
|
638 |
$sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199); |
|
639 |
||
640 |
$sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); |
|
641 |
$db->sql_query($sql); |
|
642 |
||
643 |
$db->sql_return_on_error(false); |
|
644 |
||
645 |
// Regenerate autologin/persistent login key
|
|
646 |
if ($session_autologin) |
|
647 |
{
|
|
648 |
$this->set_login_key(); |
|
649 |
}
|
|
650 |
||
651 |
// refresh data
|
|
652 |
$SID = '?sid=' . $this->session_id; |
|
653 |
$_SID = $this->session_id; |
|
654 |
$this->data = array_merge($this->data, $sql_ary); |
|
655 |
||
656 |
if (!$bot) |
|
657 |
{
|
|
658 |
$cookie_expire = $this->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000); |
|
659 |
||
660 |
$this->set_cookie('u', $this->cookie_data['u'], $cookie_expire); |
|
661 |
$this->set_cookie('k', $this->cookie_data['k'], $cookie_expire); |
|
662 |
$this->set_cookie('sid', $this->session_id, $cookie_expire); |
|
663 |
||
664 |
unset($cookie_expire); |
|
665 |
||
666 |
$sql = 'SELECT COUNT(session_id) AS sessions |
|
667 |
FROM ' . SESSIONS_TABLE . ' |
|
668 |
WHERE session_user_id = ' . (int) $this->data['user_id'] . ' |
|
669 |
AND session_time >= ' . ($this->time_now - $config['form_token_lifetime']); |
|
670 |
$result = $db->sql_query($sql); |
|
671 |
$row = $db->sql_fetchrow($result); |
|
672 |
$db->sql_freeresult($result); |
|
673 |
||
674 |
if ((int) $row['sessions'] <= 1 || empty($this->data['user_form_salt'])) |
|
675 |
{
|
|
676 |
$this->data['user_form_salt'] = unique_id(); |
|
677 |
// Update the form key
|
|
678 |
$sql = 'UPDATE ' . USERS_TABLE . ' |
|
679 |
SET user_form_salt = \'' . $db->sql_escape($this->data['user_form_salt']) . '\' |
|
680 |
WHERE user_id = ' . (int) $this->data['user_id']; |
|
681 |
$db->sql_query($sql); |
|
682 |
}
|
|
683 |
}
|
|
684 |
else
|
|
685 |
{
|
|
686 |
$this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now; |
|
687 |
||
688 |
// Update the last visit time
|
|
689 |
$sql = 'UPDATE ' . USERS_TABLE . ' |
|
690 |
SET user_lastvisit = ' . (int) $this->data['session_time'] . ' |
|
691 |
WHERE user_id = ' . (int) $this->data['user_id']; |
|
692 |
$db->sql_query($sql); |
|
693 |
||
694 |
$SID = '?sid='; |
|
695 |
$_SID = ''; |
|
696 |
}
|
|
697 |
||
698 |
return true; |
|
699 |
}
|
|
700 |
||
701 |
/**
|
|
702 |
* Kills a session
|
|
703 |
*
|
|
704 |
* This method does what it says on the tin. It will delete a pre-existing session.
|
|
705 |
* It resets cookie information (destroying any autologin key within that cookie data)
|
|
706 |
* and update the users information from the relevant session data. It will then
|
|
707 |
* grab guest user information.
|
|
708 |
*/
|
|
709 |
function session_kill($new_session = true) |
|
710 |
{
|
|
711 |
global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx; |
|
712 |
||
713 |
$sql = 'DELETE FROM ' . SESSIONS_TABLE . " |
|
714 |
WHERE session_id = '" . $db->sql_escape($this->session_id) . "' |
|
715 |
AND session_user_id = " . (int) $this->data['user_id']; |
|
716 |
$db->sql_query($sql); |
|
717 |
||
718 |
// Allow connecting logout with external auth method logout
|
|
719 |
$method = basename(trim($config['auth_method'])); |
|
720 |
include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx); |
|
721 |
||
722 |
$method = 'logout_' . $method; |
|
723 |
if (function_exists($method)) |
|
724 |
{
|
|
725 |
$method($this->data, $new_session); |
|
726 |
}
|
|
727 |
||
728 |
if ($this->data['user_id'] != ANONYMOUS) |
|
729 |
{
|
|
730 |
// Delete existing session, update last visit info first!
|
|
731 |
if (!isset($this->data['session_time'])) |
|
732 |
{
|
|
733 |
$this->data['session_time'] = time(); |
|
734 |
}
|
|
735 |
||
736 |
$sql = 'UPDATE ' . USERS_TABLE . ' |
|
737 |
SET user_lastvisit = ' . (int) $this->data['session_time'] . ' |
|
738 |
WHERE user_id = ' . (int) $this->data['user_id']; |
|
739 |
$db->sql_query($sql); |
|
740 |
||
741 |
if ($this->cookie_data['k']) |
|
742 |
{
|
|
743 |
$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' |
|
744 |
WHERE user_id = ' . (int) $this->data['user_id'] . " |
|
745 |
AND key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'"; |
|
746 |
$db->sql_query($sql); |
|
747 |
}
|
|
748 |
||
749 |
// Reset the data array
|
|
750 |
$this->data = array(); |
|
751 |
||
752 |
$sql = 'SELECT * |
|
753 |
FROM ' . USERS_TABLE . ' |
|
754 |
WHERE user_id = ' . ANONYMOUS; |
|
755 |
$result = $db->sql_query($sql); |
|
756 |
$this->data = $db->sql_fetchrow($result); |
|
757 |
$db->sql_freeresult($result); |
|
758 |
}
|
|
759 |
||
760 |
$cookie_expire = $this->time_now - 31536000; |
|
761 |
$this->set_cookie('u', '', $cookie_expire); |
|
762 |
$this->set_cookie('k', '', $cookie_expire); |
|
763 |
$this->set_cookie('sid', '', $cookie_expire); |
|
764 |
unset($cookie_expire); |
|
765 |
||
766 |
$SID = '?sid='; |
|
767 |
$this->session_id = $_SID = ''; |
|
768 |
||
769 |
// To make sure a valid session is created we create one for the anonymous user
|
|
770 |
if ($new_session) |
|
771 |
{
|
|
772 |
$this->session_create(ANONYMOUS); |
|
773 |
}
|
|
774 |
||
775 |
return true; |
|
776 |
}
|
|
777 |
||
778 |
/**
|
|
779 |
* Session garbage collection
|
|
780 |
*
|
|
781 |
* This looks a lot more complex than it really is. Effectively we are
|
|
782 |
* deleting any sessions older than an admin definable limit. Due to the
|
|
783 |
* way in which we maintain session data we have to ensure we update user
|
|
784 |
* data before those sessions are destroyed. In addition this method
|
|
785 |
* removes autologin key information that is older than an admin defined
|
|
786 |
* limit.
|
|
787 |
*/
|
|
788 |
function session_gc() |
|
789 |
{
|
|
790 |
global $db, $config; |
|
791 |
||
792 |
$batch_size = 10; |
|
793 |
||
794 |
if (!$this->time_now) |
|
795 |
{
|
|
796 |
$this->time_now = time(); |
|
797 |
}
|
|
798 |
||
799 |
// Firstly, delete guest sessions
|
|
800 |
$sql = 'DELETE FROM ' . SESSIONS_TABLE . ' |
|
801 |
WHERE session_user_id = ' . ANONYMOUS . ' |
|
802 |
AND session_time < ' . (int) ($this->time_now - $config['session_length']); |
|
803 |
$db->sql_query($sql); |
|
804 |
||
805 |
// Get expired sessions, only most recent for each user
|
|
806 |
$sql = 'SELECT session_user_id, session_page, MAX(session_time) AS recent_time |
|
807 |
FROM ' . SESSIONS_TABLE . ' |
|
808 |
WHERE session_time < ' . ($this->time_now - $config['session_length']) . ' |
|
809 |
GROUP BY session_user_id, session_page'; |
|
810 |
$result = $db->sql_query_limit($sql, $batch_size); |
|
811 |
||
812 |
$del_user_id = array(); |
|
813 |
$del_sessions = 0; |
|
814 |
||
815 |
while ($row = $db->sql_fetchrow($result)) |
|
816 |
{
|
|
817 |
$sql = 'UPDATE ' . USERS_TABLE . ' |
|
818 |
SET user_lastvisit = ' . (int) $row['recent_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "' |
|
819 |
WHERE user_id = " . (int) $row['session_user_id']; |
|
820 |
$db->sql_query($sql); |
|
821 |
||
822 |
$del_user_id[] = (int) $row['session_user_id']; |
|
823 |
$del_sessions++; |
|
824 |
}
|
|
825 |
$db->sql_freeresult($result); |
|
826 |
||
827 |
if (sizeof($del_user_id)) |
|
828 |
{
|
|
829 |
// Delete expired sessions
|
|
830 |
$sql = 'DELETE FROM ' . SESSIONS_TABLE . ' |
|
831 |
WHERE ' . $db->sql_in_set('session_user_id', $del_user_id) . ' |
|
832 |
AND session_time < ' . ($this->time_now - $config['session_length']); |
|
833 |
$db->sql_query($sql); |
|
834 |
}
|
|
835 |
||
836 |
if ($del_sessions < $batch_size) |
|
837 |
{
|
|
838 |
// Less than 10 users, update gc timer ... else we want gc
|
|
839 |
// called again to delete other sessions
|
|
840 |
set_config('session_last_gc', $this->time_now, true); |
|
841 |
||
842 |
if ($config['max_autologin_time']) |
|
843 |
{
|
|
844 |
$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' |
|
845 |
WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time'])); |
|
846 |
$db->sql_query($sql); |
|
847 |
}
|
|
848 |
$this->confirm_gc(); |
|
849 |
}
|
|
850 |
||
851 |
return; |
|
852 |
}
|
|
853 |
||
854 |
function confirm_gc($type = 0) |
|
855 |
{
|
|
856 |
global $db, $config; |
|
857 |
||
858 |
$sql = 'SELECT DISTINCT c.session_id |
|
859 |
FROM ' . CONFIRM_TABLE . ' c |
|
860 |
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (c.session_id = s.session_id) |
|
861 |
WHERE s.session_id IS NULL' . |
|
862 |
((empty($type)) ? '' : ' AND c.confirm_type = ' . (int) $type); |
|
863 |
$result = $db->sql_query($sql); |
|
864 |
||
865 |
if ($row = $db->sql_fetchrow($result)) |
|
866 |
{
|
|
867 |
$sql_in = array(); |
|
868 |
do
|
|
869 |
{
|
|
870 |
$sql_in[] = (string) $row['session_id']; |
|
871 |
}
|
|
872 |
while ($row = $db->sql_fetchrow($result)); |
|
873 |
||
874 |
if (sizeof($sql_in)) |
|
875 |
{
|
|
876 |
$sql = 'DELETE FROM ' . CONFIRM_TABLE . ' |
|
877 |
WHERE ' . $db->sql_in_set('session_id', $sql_in); |
|
878 |
$db->sql_query($sql); |
|
879 |
}
|
|
880 |
}
|
|
881 |
$db->sql_freeresult($result); |
|
882 |
}
|
|
883 |
||
884 |
||
885 |
/**
|
|
886 |
* Sets a cookie
|
|
887 |
*
|
|
888 |
* Sets a cookie of the given name with the specified data for the given length of time.
|
|
889 |
*/
|
|
890 |
function set_cookie($name, $cookiedata, $cookietime) |
|
891 |
{
|
|
892 |
global $config; |
|
893 |
||
894 |
$name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata); |
|
895 |
$expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime); |
|
896 |
$domain = (!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain']; |
|
897 |
||
898 |
header('Set-Cookie: ' . $name_data . '; expires=' . $expire . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false); |
|
899 |
}
|
|
900 |
||
901 |
/**
|
|
902 |
* Check for banned user
|
|
903 |
*
|
|
904 |
* Checks whether the supplied user is banned by id, ip or email. If no parameters
|
|
905 |
* are passed to the method pre-existing session data is used. If $return is false
|
|
906 |
* this routine does not return on finding a banned user, it outputs a relevant
|
|
907 |
* message and stops execution.
|
|
908 |
*
|
|
909 |
* @param string|array $user_ips Can contain a string with one IP or an array of multiple IPs
|
|
910 |
*/
|
|
911 |
function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false) |
|
912 |
{
|
|
913 |
global $config, $db; |
|
914 |
||
915 |
if (defined('IN_CHECK_BAN')) |
|
916 |
{
|
|
917 |
return; |
|
918 |
}
|
|
919 |
||
920 |
$banned = false; |
|
921 |
$cache_ttl = 3600; |
|
922 |
$where_sql = array(); |
|
923 |
||
924 |
$sql = 'SELECT ban_ip, ban_userid, ban_email, ban_exclude, ban_give_reason, ban_end |
|
925 |
FROM ' . BANLIST_TABLE . ' |
|
926 |
WHERE '; |
|
927 |
||
928 |
// Determine which entries to check, only return those
|
|
929 |
if ($user_email === false) |
|
930 |
{
|
|
931 |
$where_sql[] = "ban_email = ''"; |
|
932 |
}
|
|
933 |
||
934 |
if ($user_ips === false) |
|
935 |
{
|
|
936 |
$where_sql[] = "(ban_ip = '' OR ban_exclude = 1)"; |
|
937 |
}
|
|
938 |
||
939 |
if ($user_id === false) |
|
940 |
{
|
|
941 |
$where_sql[] = '(ban_userid = 0 OR ban_exclude = 1)'; |
|
942 |
}
|
|
943 |
else
|
|
944 |
{
|
|
945 |
$cache_ttl = ($user_id == ANONYMOUS) ? 3600 : 0; |
|
946 |
$_sql = '(ban_userid = ' . $user_id; |
|
947 |
||
948 |
if ($user_email !== false) |
|
949 |
{
|
|
950 |
$_sql .= " OR ban_email <> ''"; |
|
951 |
}
|
|
952 |
||
953 |
if ($user_ips !== false) |
|
954 |
{
|
|
955 |
$_sql .= " OR ban_ip <> ''"; |
|
956 |
}
|
|
957 |
||
958 |
$_sql .= ')'; |
|
959 |
||
960 |
$where_sql[] = $_sql; |
|
961 |
}
|
|
962 |
||
963 |
$sql .= (sizeof($where_sql)) ? implode(' AND ', $where_sql) : ''; |
|
964 |
$result = $db->sql_query($sql, $cache_ttl); |
|
965 |
||
966 |
$ban_triggered_by = 'user'; |
|
967 |
while ($row = $db->sql_fetchrow($result)) |
|
968 |
{
|
|
969 |
if ($row['ban_end'] && $row['ban_end'] < time()) |
|
970 |
{
|
|
971 |
continue; |
|
972 |
}
|
|
973 |
||
974 |
$ip_banned = false; |
|
975 |
if (!empty($row['ban_ip'])) |
|
976 |
{
|
|
977 |
if (!is_array($user_ips)) |
|
978 |
{
|
|
979 |
$ip_banned = preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ips); |
|
980 |
}
|
|
981 |
else
|
|
982 |
{
|
|
983 |
foreach ($user_ips as $user_ip) |
|
984 |
{
|
|
985 |
if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ip)) |
|
986 |
{
|
|
987 |
$ip_banned = true; |
|
988 |
break; |
|
989 |
}
|
|
990 |
}
|
|
991 |
}
|
|
992 |
}
|
|
993 |
||
994 |
if ((!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id) || |
|
995 |
$ip_banned || |
|
996 |
(!empty($row['ban_email']) && preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_email'], '#')) . '$#i', $user_email))) |
|
997 |
{
|
|
998 |
if (!empty($row['ban_exclude'])) |
|
999 |
{
|
|
1000 |
$banned = false; |
|
1001 |
break; |
|
1002 |
}
|
|
1003 |
else
|
|
1004 |
{
|
|
1005 |
$banned = true; |
|
1006 |
$ban_row = $row; |
|
1007 |
||
1008 |
if (!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id) |
|
1009 |
{
|
|
1010 |
$ban_triggered_by = 'user'; |
|
1011 |
}
|
|
1012 |
else if ($ip_banned) |
|
1013 |
{
|
|
1014 |
$ban_triggered_by = 'ip'; |
|
1015 |
}
|
|
1016 |
else
|
|
1017 |
{
|
|
1018 |
$ban_triggered_by = 'email'; |
|
1019 |
}
|
|
1020 |
||
1021 |
// Don't break. Check if there is an exclude rule for this user
|
|
1022 |
}
|
|
1023 |
}
|
|
1024 |
}
|
|
1025 |
$db->sql_freeresult($result); |
|
1026 |
||
1027 |
if ($banned && !$return) |
|
1028 |
{
|
|
1029 |
global $template; |
|
1030 |
||
1031 |
// If the session is empty we need to create a valid one...
|
|
1032 |
if (empty($this->session_id)) |
|
1033 |
{
|
|
1034 |
// This seems to be no longer needed? - #14971
|
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
1035 |
//$this->session_create(ANONYMOUS);
|
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
1036 |
}
|
1037 |
||
1038 |
// Initiate environment ... since it won't be set at this stage
|
|
1039 |
$this->setup(); |
|
1040 |
||
1041 |
// Logout the user, banned users are unable to use the normal 'logout' link
|
|
1042 |
if ($this->data['user_id'] != ANONYMOUS) |
|
1043 |
{
|
|
1044 |
$this->session_kill(); |
|
1045 |
}
|
|
1046 |
||
1047 |
// We show a login box here to allow founders accessing the board if banned by IP
|
|
1048 |
if (defined('IN_LOGIN') && $this->data['user_id'] == ANONYMOUS) |
|
1049 |
{
|
|
1050 |
global $phpEx; |
|
1051 |
||
1052 |
$this->setup('ucp'); |
|
1053 |
$this->data['is_registered'] = $this->data['is_bot'] = false; |
|
1054 |
||
1055 |
// Set as a precaution to allow login_box() handling this case correctly as well as this function not being executed again.
|
|
1056 |
define('IN_CHECK_BAN', 1); |
|
1057 |
||
1058 |
login_box("index.$phpEx"); |
|
1059 |
||
1060 |
// The false here is needed, else the user is able to circumvent the ban.
|
|
1061 |
$this->session_kill(false); |
|
1062 |
}
|
|
1063 |
||
1064 |
// Ok, we catch the case of an empty session id for the anonymous user...
|
|
1065 |
// This can happen if the user is logging in, banned by username and the login_box() being called "again".
|
|
1066 |
if (empty($this->session_id) && defined('IN_CHECK_BAN')) |
|
1067 |
{
|
|
1068 |
$this->session_create(ANONYMOUS); |
|
1069 |
}
|
|
1070 |
||
1071 |
||
1072 |
// Determine which message to output
|
|
1073 |
$till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : ''; |
|
1074 |
$message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM'; |
|
1075 |
||
1076 |
$message = sprintf($this->lang[$message], $till_date, '<a href="mailto:' . $config['board_contact'] . '">', '</a>'); |
|
1077 |
$message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : ''; |
|
1078 |
$message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>'; |
|
1079 |
||
1080 |
// To circumvent session_begin returning a valid value and the check_ban() not called on second page view, we kill the session again
|
|
1081 |
$this->session_kill(false); |
|
1082 |
||
1083 |
trigger_error($message); |
|
1084 |
}
|
|
1085 |
||
1086 |
return ($banned) ? true : false; |
|
1087 |
}
|
|
1088 |
||
1089 |
/**
|
|
1090 |
* Check if ip is blacklisted
|
|
1091 |
* This should be called only where absolutly necessary
|
|
1092 |
*
|
|
1093 |
* Only IPv4 (rbldns does not support AAAA records/IPv6 lookups)
|
|
1094 |
*
|
|
1095 |
* @author satmd (from the php manual)
|
|
1096 |
* @param string $mode register/post - spamcop for example is ommitted for posting
|
|
1097 |
* @return false if ip is not blacklisted, else an array([checked server], [lookup])
|
|
1098 |
*/
|
|
1099 |
function check_dnsbl($mode, $ip = false) |
|
1100 |
{
|
|
1101 |
if ($ip === false) |
|
1102 |
{
|
|
1103 |
$ip = $this->ip; |
|
1104 |
}
|
|
1105 |
||
1106 |
$dnsbl_check = array( |
|
1107 |
'list.dsbl.org' => 'http://dsbl.org/listing?', |
|
1108 |
'sbl-xbl.spamhaus.org' => 'http://www.spamhaus.org/query/bl?ip=', |
|
1109 |
);
|
|
1110 |
||
1111 |
if ($mode == 'register') |
|
1112 |
{
|
|
1113 |
$dnsbl_check['bl.spamcop.net'] = 'http://spamcop.net/bl.shtml?'; |
|
1114 |
}
|
|
1115 |
||
1116 |
if ($ip) |
|
1117 |
{
|
|
1118 |
$quads = explode('.', $ip); |
|
1119 |
$reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0]; |
|
1120 |
||
1121 |
// Need to be listed on all servers...
|
|
1122 |
$listed = true; |
|
1123 |
$info = array(); |
|
1124 |
||
1125 |
foreach ($dnsbl_check as $dnsbl => $lookup) |
|
1126 |
{
|
|
1127 |
if (phpbb_checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true) |
|
1128 |
{
|
|
1129 |
$info = array($dnsbl, $lookup . $ip); |
|
1130 |
}
|
|
1131 |
else
|
|
1132 |
{
|
|
1133 |
$listed = false; |
|
1134 |
}
|
|
1135 |
}
|
|
1136 |
||
1137 |
if ($listed) |
|
1138 |
{
|
|
1139 |
return $info; |
|
1140 |
}
|
|
1141 |
}
|
|
1142 |
||
1143 |
return false; |
|
1144 |
}
|
|
1145 |
||
1146 |
/**
|
|
1147 |
* Check if URI is blacklisted
|
|
1148 |
* This should be called only where absolutly necessary, for example on the submitted website field
|
|
1149 |
* This function is not in use at the moment and is only included for testing purposes, it may not work at all!
|
|
1150 |
* This means it is untested at the moment and therefore commented out
|
|
1151 |
*
|
|
1152 |
* @param string $uri URI to check
|
|
1153 |
* @return true if uri is on blacklist, else false. Only blacklist is checked (~zero FP), no grey lists
|
|
1154 |
function check_uribl($uri)
|
|
1155 |
{
|
|
1156 |
// Normally parse_url() is not intended to parse uris
|
|
1157 |
// We need to get the top-level domain name anyway... change.
|
|
1158 |
$uri = parse_url($uri);
|
|
1159 |
||
1160 |
if ($uri === false || empty($uri['host']))
|
|
1161 |
{
|
|
1162 |
return false;
|
|
1163 |
}
|
|
1164 |
||
1165 |
$uri = trim($uri['host']);
|
|
1166 |
||
1167 |
if ($uri)
|
|
1168 |
{
|
|
1169 |
// One problem here... the return parameter for the "windows" method is different from what
|
|
1170 |
// we expect... this may render this check useless...
|
|
1171 |
if (phpbb_checkdnsrr($uri . '.multi.uribl.com.', 'A') === true)
|
|
1172 |
{
|
|
1173 |
return true;
|
|
1174 |
}
|
|
1175 |
}
|
|
1176 |
||
1177 |
return false;
|
|
1178 |
}
|
|
1179 |
*/
|
|
1180 |
||
1181 |
/**
|
|
1182 |
* Set/Update a persistent login key
|
|
1183 |
*
|
|
1184 |
* This method creates or updates a persistent session key. When a user makes
|
|
1185 |
* use of persistent (formerly auto-) logins a key is generated and stored in the
|
|
1186 |
* DB. When they revisit with the same key it's automatically updated in both the
|
|
1187 |
* DB and cookie. Multiple keys may exist for each user representing different
|
|
1188 |
* browsers or locations. As with _any_ non-secure-socket no passphrase login this
|
|
1189 |
* remains vulnerable to exploit.
|
|
1190 |
*/
|
|
1191 |
function set_login_key($user_id = false, $key = false, $user_ip = false) |
|
1192 |
{
|
|
1193 |
global $config, $db; |
|
1194 |
||
1195 |
$user_id = ($user_id === false) ? $this->data['user_id'] : $user_id; |
|
1196 |
$user_ip = ($user_ip === false) ? $this->ip : $user_ip; |
|
1197 |
$key = ($key === false) ? (($this->cookie_data['k']) ? $this->cookie_data['k'] : false) : $key; |
|
1198 |
||
1199 |
$key_id = unique_id(hexdec(substr($this->session_id, 0, 8))); |
|
1200 |
||
1201 |
$sql_ary = array( |
|
1202 |
'key_id' => (string) md5($key_id), |
|
1203 |
'last_ip' => (string) $this->ip, |
|
1204 |
'last_login' => (int) time() |
|
1205 |
);
|
|
1206 |
||
1207 |
if (!$key) |
|
1208 |
{
|
|
1209 |
$sql_ary += array( |
|
1210 |
'user_id' => (int) $user_id |
|
1211 |
);
|
|
1212 |
}
|
|
1213 |
||
1214 |
if ($key) |
|
1215 |
{
|
|
1216 |
$sql = 'UPDATE ' . SESSIONS_KEYS_TABLE . ' |
|
1217 |
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' |
|
1218 |
WHERE user_id = ' . (int) $user_id . " |
|
1219 |
AND key_id = '" . $db->sql_escape(md5($key)) . "'"; |
|
1220 |
}
|
|
1221 |
else
|
|
1222 |
{
|
|
1223 |
$sql = 'INSERT INTO ' . SESSIONS_KEYS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); |
|
1224 |
}
|
|
1225 |
$db->sql_query($sql); |
|
1226 |
||
1227 |
$this->cookie_data['k'] = $key_id; |
|
1228 |
||
1229 |
return false; |
|
1230 |
}
|
|
1231 |
||
1232 |
/**
|
|
1233 |
* Reset all login keys for the specified user
|
|
1234 |
*
|
|
1235 |
* This method removes all current login keys for a specified (or the current)
|
|
1236 |
* user. It will be called on password change to render old keys unusable
|
|
1237 |
*/
|
|
1238 |
function reset_login_keys($user_id = false) |
|
1239 |
{
|
|
1240 |
global $config, $db; |
|
1241 |
||
1242 |
$user_id = ($user_id === false) ? $this->data['user_id'] : $user_id; |
|
1243 |
||
1244 |
$sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' |
|
1245 |
WHERE user_id = ' . (int) $user_id; |
|
1246 |
$db->sql_query($sql); |
|
1247 |
||
1248 |
// Let's also clear any current sessions for the specified user_id
|
|
1249 |
// If it's the current user then we'll leave this session intact
|
|
1250 |
$sql_where = 'session_user_id = ' . (int) $user_id; |
|
1251 |
$sql_where .= ($user_id === $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : ''; |
|
1252 |
||
1253 |
$sql = 'DELETE FROM ' . SESSIONS_TABLE . " |
|
1254 |
WHERE $sql_where"; |
|
1255 |
$db->sql_query($sql); |
|
1256 |
||
1257 |
// We're changing the password of the current user and they have a key
|
|
1258 |
// Lets regenerate it to be safe
|
|
1259 |
if ($user_id === $this->data['user_id'] && $this->cookie_data['k']) |
|
1260 |
{
|
|
1261 |
$this->set_login_key($user_id); |
|
1262 |
}
|
|
1263 |
}
|
|
1264 |
}
|
|
1265 |
||
1266 |
||
1267 |
/**
|
|
1268 |
* Base user class
|
|
1269 |
*
|
|
1270 |
* This is the overarching class which contains (through session extend)
|
|
1271 |
* all methods utilised for user functionality during a session.
|
|
1272 |
*
|
|
1273 |
* @package phpBB3
|
|
1274 |
*/
|
|
1275 |
class user extends session |
|
1276 |
{
|
|
1277 |
var $lang = array(); |
|
1278 |
var $help = array(); |
|
1279 |
var $theme = array(); |
|
1280 |
var $date_format; |
|
1281 |
var $timezone; |
|
1282 |
var $dst; |
|
1283 |
||
1284 |
var $lang_name; |
|
1285 |
var $lang_id = false; |
|
1286 |
var $lang_path; |
|
1287 |
var $img_lang; |
|
1288 |
var $img_array = array(); |
|
1289 |
||
1290 |
// Able to add new option (id 7)
|
|
1291 |
var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10); |
|
1292 |
var $keyvalues = array(); |
|
1293 |
||
1294 |
/**
|
|
1295 |
* Setup basic user-specific items (style, language, ...)
|
|
1296 |
*/
|
|
1297 |
function setup($lang_set = false, $style = false) |
|
1298 |
{
|
|
1299 |
global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; |
|
1300 |
||
1301 |
if ($this->data['user_id'] != ANONYMOUS) |
|
1302 |
{
|
|
1303 |
$this->lang_name = (file_exists($phpbb_root_path . 'language/' . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']); |
|
1304 |
$this->lang_path = $phpbb_root_path . 'language/' . $this->lang_name . '/'; |
|
1305 |
||
1306 |
$this->date_format = $this->data['user_dateformat']; |
|
1307 |
$this->timezone = $this->data['user_timezone'] * 3600; |
|
1308 |
$this->dst = $this->data['user_dst'] * 3600; |
|
1309 |
}
|
|
1310 |
else
|
|
1311 |
{
|
|
1312 |
$this->lang_name = basename($config['default_lang']); |
|
1313 |
$this->lang_path = $phpbb_root_path . 'language/' . $this->lang_name . '/'; |
|
1314 |
$this->date_format = $config['default_dateformat']; |
|
1315 |
$this->timezone = $config['board_timezone'] * 3600; |
|
1316 |
$this->dst = $config['board_dst'] * 3600; |
|
1317 |
||
1318 |
/**
|
|
1319 |
* If a guest user is surfing, we try to guess his/her language first by obtaining the browser language
|
|
1320 |
* If re-enabled we need to make sure only those languages installed are checked
|
|
1321 |
* Commented out so we do not loose the code.
|
|
1322 |
||
1323 |
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
|
1324 |
{
|
|
1325 |
$accept_lang_ary = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
|
1326 |
||
1327 |
foreach ($accept_lang_ary as $accept_lang)
|
|
1328 |
{
|
|
1329 |
// Set correct format ... guess full xx_YY form
|
|
1330 |
$accept_lang = substr($accept_lang, 0, 2) . '_' . strtoupper(substr($accept_lang, 3, 2));
|
|
1331 |
$accept_lang = basename($accept_lang);
|
|
1332 |
||
1333 |
if (file_exists($phpbb_root_path . 'language/' . $accept_lang . "/common.$phpEx"))
|
|
1334 |
{
|
|
1335 |
$this->lang_name = $config['default_lang'] = $accept_lang;
|
|
1336 |
$this->lang_path = $phpbb_root_path . 'language/' . $accept_lang . '/';
|
|
1337 |
break;
|
|
1338 |
}
|
|
1339 |
else
|
|
1340 |
{
|
|
1341 |
// No match on xx_YY so try xx
|
|
1342 |
$accept_lang = substr($accept_lang, 0, 2);
|
|
1343 |
$accept_lang = basename($accept_lang);
|
|
1344 |
||
1345 |
if (file_exists($phpbb_root_path . 'language/' . $accept_lang . "/common.$phpEx"))
|
|
1346 |
{
|
|
1347 |
$this->lang_name = $config['default_lang'] = $accept_lang;
|
|
1348 |
$this->lang_path = $phpbb_root_path . 'language/' . $accept_lang . '/';
|
|
1349 |
break;
|
|
1350 |
}
|
|
1351 |
}
|
|
1352 |
}
|
|
1353 |
}
|
|
1354 |
*/
|
|
1355 |
}
|
|
1356 |
||
1357 |
// We include common language file here to not load it every time a custom language file is included
|
|
1358 |
$lang = &$this->lang; |
|
1359 |
||
1360 |
if ((@include $this->lang_path . "common.$phpEx") === false) |
|
1361 |
{
|
|
1362 |
die('Language file ' . $this->lang_name . "/common.$phpEx" . " couldn't be opened."); |
|
1363 |
}
|
|
1364 |
||
1365 |
$this->add_lang($lang_set); |
|
1366 |
unset($lang_set); |
|
1367 |
||
1368 |
if (!empty($_GET['style']) && $auth->acl_get('a_styles')) |
|
1369 |
{
|
|
1370 |
global $SID, $_EXTRA_URL; |
|
1371 |
||
1372 |
$style = request_var('style', 0); |
|
1373 |
$SID .= '&style=' . $style; |
|
1374 |
$_EXTRA_URL = array('style=' . $style); |
|
1375 |
}
|
|
1376 |
else
|
|
1377 |
{
|
|
1378 |
// Set up style
|
|
1379 |
$style = ($style) ? $style : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']); |
|
1380 |
}
|
|
1381 |
||
1382 |
$sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name |
|
1383 |
FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i |
|
1384 |
WHERE s.style_id = $style |
|
1385 |
AND t.template_id = s.template_id
|
|
1386 |
AND c.theme_id = s.theme_id
|
|
1387 |
AND i.imageset_id = s.imageset_id"; |
|
1388 |
$result = $db->sql_query($sql, 3600); |
|
1389 |
$this->theme = $db->sql_fetchrow($result); |
|
1390 |
$db->sql_freeresult($result); |
|
1391 |
||
1392 |
// User has wrong style
|
|
1393 |
if (!$this->theme && $style == $this->data['user_style']) |
|
1394 |
{
|
|
1395 |
$style = $this->data['user_style'] = $config['default_style']; |
|
1396 |
||
1397 |
$sql = 'UPDATE ' . USERS_TABLE . " |
|
1398 |
SET user_style = $style |
|
1399 |
WHERE user_id = {$this->data['user_id']}"; |
|
1400 |
$db->sql_query($sql); |
|
1401 |
||
1402 |
$sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name |
|
1403 |
FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i |
|
1404 |
WHERE s.style_id = $style |
|
1405 |
AND t.template_id = s.template_id
|
|
1406 |
AND c.theme_id = s.theme_id
|
|
1407 |
AND i.imageset_id = s.imageset_id"; |
|
1408 |
$result = $db->sql_query($sql, 3600); |
|
1409 |
$this->theme = $db->sql_fetchrow($result); |
|
1410 |
$db->sql_freeresult($result); |
|
1411 |
}
|
|
1412 |
||
1413 |
if (!$this->theme) |
|
1414 |
{
|
|
1415 |
trigger_error('Could not get style data', E_USER_ERROR); |
|
1416 |
}
|
|
1417 |
||
1418 |
// Now parse the cfg file and cache it
|
|
1419 |
$parsed_items = $cache->obtain_cfg_items($this->theme); |
|
1420 |
||
1421 |
// We are only interested in the theme configuration for now
|
|
1422 |
$parsed_items = $parsed_items['theme']; |
|
1423 |
||
1424 |
$check_for = array( |
|
1425 |
'parse_css_file' => (int) 0, |
|
1426 |
'pagination_sep' => (string) ', ' |
|
1427 |
);
|
|
1428 |
||
1429 |
foreach ($check_for as $key => $default_value) |
|
1430 |
{
|
|
1431 |
$this->theme[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value; |
|
1432 |
settype($this->theme[$key], gettype($default_value)); |
|
1433 |
||
1434 |
if (is_string($default_value)) |
|
1435 |
{
|
|
1436 |
$this->theme[$key] = htmlspecialchars($this->theme[$key]); |
|
1437 |
}
|
|
1438 |
}
|
|
1439 |
||
1440 |
// If the style author specified the theme needs to be cached
|
|
1441 |
// (because of the used paths and variables) than make sure it is the case.
|
|
1442 |
// For example, if the theme uses language-specific images it needs to be stored in db.
|
|
1443 |
if (!$this->theme['theme_storedb'] && $this->theme['parse_css_file']) |
|
1444 |
{
|
|
1445 |
$this->theme['theme_storedb'] = 1; |
|
1446 |
||
1447 |
$stylesheet = file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/stylesheet.css"); |
|
1448 |
// Match CSS imports
|
|
1449 |
$matches = array(); |
|
1450 |
preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches); |
|
1451 |
||
1452 |
if (sizeof($matches)) |
|
1453 |
{
|
|
1454 |
$content = ''; |
|
1455 |
foreach ($matches[0] as $idx => $match) |
|
1456 |
{
|
|
1457 |
if ($content = @file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/" . $matches[1][$idx])) |
|
1458 |
{
|
|
1459 |
$content = trim($content); |
|
1460 |
}
|
|
1461 |
else
|
|
1462 |
{
|
|
1463 |
$content = ''; |
|
1464 |
}
|
|
1465 |
$stylesheet = str_replace($match, $content, $stylesheet); |
|
1466 |
}
|
|
1467 |
unset($content); |
|
1468 |
}
|
|
1469 |
||
1470 |
$stylesheet = str_replace('./', 'styles/' . $this->theme['theme_path'] . '/theme/', $stylesheet); |
|
1471 |
||
1472 |
$sql_ary = array( |
|
1473 |
'theme_data' => $stylesheet, |
|
1474 |
'theme_mtime' => time(), |
|
1475 |
'theme_storedb' => 1 |
|
1476 |
);
|
|
1477 |
||
1478 |
$sql = 'UPDATE ' . STYLES_THEME_TABLE . ' |
|
1479 |
SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' |
|
1480 |
WHERE theme_id = ' . $this->theme['theme_id']; |
|
1481 |
$db->sql_query($sql); |
|
1482 |
||
1483 |
unset($sql_ary); |
|
1484 |
}
|
|
1485 |
||
1486 |
$template->set_template(); |
|
1487 |
||
1488 |
$this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang']; |
|
1489 |
||
1490 |
$sql = 'SELECT image_name, image_filename, image_lang, image_height, image_width |
|
1491 |
FROM ' . STYLES_IMAGESET_DATA_TABLE . ' |
|
1492 |
WHERE imageset_id = ' . $this->theme['imageset_id'] . " |
|
1493 |
AND image_lang IN ('" . $db->sql_escape($this->img_lang) . "', '')"; |
|
1494 |
$result = $db->sql_query($sql, 3600); |
|
1495 |
||
1496 |
$localised_images = false; |
|
1497 |
while ($row = $db->sql_fetchrow($result)) |
|
1498 |
{
|
|
1499 |
if ($row['image_lang']) |
|
1500 |
{
|
|
1501 |
$localised_images = true; |
|
1502 |
}
|
|
1503 |
||
1504 |
$this->img_array[$row['image_name']] = $row; |
|
1505 |
}
|
|
1506 |
$db->sql_freeresult($result); |
|
1507 |
||
1508 |
// there were no localised images, try to refresh the localised imageset for the user's language
|
|
1509 |
if (!$localised_images) |
|
1510 |
{
|
|
1511 |
// Attention: this code ignores the image definition list from acp_styles and just takes everything
|
|
1512 |
// that the config file contains
|
|
1513 |
$sql_ary = array(); |
|
1514 |
||
1515 |
$db->sql_transaction('begin'); |
|
1516 |
||
1517 |
$sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . ' |
|
1518 |
WHERE imageset_id = ' . $this->theme['imageset_id'] . ' |
|
1519 |
AND image_lang = \'' . $db->sql_escape($this->img_lang) . '\''; |
|
1520 |
$result = $db->sql_query($sql); |
|
1521 |
||
1522 |
if (@file_exists("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg")) |
|
1523 |
{
|
|
1524 |
$cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg"); |
|
1525 |
foreach ($cfg_data_imageset_data as $image_name => $value) |
|
1526 |
{
|
|
1527 |
if (strpos($value, '*') !== false) |
|
1528 |
{
|
|
1529 |
if (substr($value, -1, 1) === '*') |
|
1530 |
{
|
|
1531 |
list($image_filename, $image_height) = explode('*', $value); |
|
1532 |
$image_width = 0; |
|
1533 |
}
|
|
1534 |
else
|
|
1535 |
{
|
|
1536 |
list($image_filename, $image_height, $image_width) = explode('*', $value); |
|
1537 |
}
|
|
1538 |
}
|
|
1539 |
else
|
|
1540 |
{
|
|
1541 |
$image_filename = $value; |
|
1542 |
$image_height = $image_width = 0; |
|
1543 |
}
|
|
1544 |
||
1545 |
if (strpos($image_name, 'img_') === 0 && $image_filename) |
|
1546 |
{
|
|
1547 |
$image_name = substr($image_name, 4); |
|
1548 |
$sql_ary[] = array( |
|
1549 |
'image_name' => (string) $image_name, |
|
1550 |
'image_filename' => (string) $image_filename, |
|
1551 |
'image_height' => (int) $image_height, |
|
1552 |
'image_width' => (int) $image_width, |
|
1553 |
'imageset_id' => (int) $this->theme['imageset_id'], |
|
1554 |
'image_lang' => (string) $this->img_lang, |
|
1555 |
);
|
|
1556 |
}
|
|
1557 |
}
|
|
1558 |
}
|
|
1559 |
||
1560 |
if (sizeof($sql_ary)) |
|
1561 |
{
|
|
1562 |
$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary); |
|
1563 |
$db->sql_transaction('commit'); |
|
1564 |
$cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE); |
|
1565 |
||
1566 |
add_log('admin', 'LOG_IMAGESET_LANG_REFRESHED', $this->theme['imageset_name'], $this->img_lang); |
|
1567 |
}
|
|
1568 |
else
|
|
1569 |
{
|
|
1570 |
$db->sql_transaction('commit'); |
|
1571 |
add_log('admin', 'LOG_IMAGESET_LANG_MISSING', $this->theme['imageset_name'], $this->img_lang); |
|
1572 |
}
|
|
1573 |
}
|
|
1574 |
||
1575 |
// Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes...
|
|
1576 |
// After calling it we continue script execution...
|
|
1577 |
phpbb_user_session_handler(); |
|
1578 |
||
1579 |
// If this function got called from the error handler we are finished here.
|
|
1580 |
if (defined('IN_ERROR_HANDLER')) |
|
1581 |
{
|
|
1582 |
return; |
|
1583 |
}
|
|
1584 |
||
1585 |
// Disable board if the install/ directory is still present
|
|
1586 |
// For the brave development army we do not care about this, else we need to comment out this everytime we develop locally
|
|
1587 |
if (!defined('DEBUG_EXTRA') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install')) |
|
1588 |
{
|
|
1589 |
// Adjust the message slightly according to the permissions
|
|
1590 |
if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_')) |
|
1591 |
{
|
|
1592 |
$message = 'REMOVE_INSTALL'; |
|
1593 |
}
|
|
1594 |
else
|
|
1595 |
{
|
|
1596 |
$message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE'; |
|
1597 |
}
|
|
1598 |
trigger_error($message); |
|
1599 |
}
|
|
1600 |
||
1601 |
// Is board disabled and user not an admin or moderator?
|
|
1602 |
if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) |
|
1603 |
{
|
|
1604 |
header('HTTP/1.1 503 Service Unavailable'); |
|
1605 |
||
1606 |
$message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE'; |
|
1607 |
trigger_error($message); |
|
1608 |
}
|
|
1609 |
||
1610 |
// Is load exceeded?
|
|
1611 |
if ($config['limit_load'] && $this->load !== false) |
|
1612 |
{
|
|
1613 |
if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN')) |
|
1614 |
{
|
|
1615 |
// Set board disabled to true to let the admins/mods get the proper notification
|
|
1616 |
$config['board_disable'] = '1'; |
|
1617 |
||
1618 |
if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_')) |
|
1619 |
{
|
|
1620 |
header('HTTP/1.1 503 Service Unavailable'); |
|
1621 |
trigger_error('BOARD_UNAVAILABLE'); |
|
1622 |
}
|
|
1623 |
}
|
|
1624 |
}
|
|
1625 |
||
1626 |
if (isset($this->data['session_viewonline'])) |
|
1627 |
{
|
|
1628 |
// Make sure the user is able to hide his session
|
|
1629 |
if (!$this->data['session_viewonline']) |
|
1630 |
{
|
|
1631 |
// Reset online status if not allowed to hide the session...
|
|
1632 |
if (!$auth->acl_get('u_hideonline')) |
|
1633 |
{
|
|
1634 |
$sql = 'UPDATE ' . SESSIONS_TABLE . ' |
|
1635 |
SET session_viewonline = 1
|
|
1636 |
WHERE session_user_id = ' . $this->data['user_id']; |
|
1637 |
$db->sql_query($sql); |
|
1638 |
$this->data['session_viewonline'] = 1; |
|
1639 |
}
|
|
1640 |
}
|
|
1641 |
else if (!$this->data['user_allow_viewonline']) |
|
1642 |
{
|
|
1643 |
// the user wants to hide and is allowed to -> cloaking device on.
|
|
1644 |
if ($auth->acl_get('u_hideonline')) |
|
1645 |
{
|
|
1646 |
$sql = 'UPDATE ' . SESSIONS_TABLE . ' |
|
1647 |
SET session_viewonline = 0
|
|
1648 |
WHERE session_user_id = ' . $this->data['user_id']; |
|
1649 |
$db->sql_query($sql); |
|
1650 |
$this->data['session_viewonline'] = 0; |
|
1651 |
}
|
|
1652 |
}
|
|
1653 |
}
|
|
1654 |
||
1655 |
||
1656 |
// Does the user need to change their password? If so, redirect to the
|
|
1657 |
// ucp profile reg_details page ... of course do not redirect if we're already in the ucp
|
|
1658 |
if (!defined('IN_ADMIN') && !defined('ADMIN_START') && $config['chg_passforce'] && $this->data['is_registered'] && $auth->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400)) |
|
1659 |
{
|
|
1660 |
if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != "ucp.$phpEx") |
|
1661 |
{
|
|
1662 |
redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=profile&mode=reg_details')); |
|
1663 |
}
|
|
1664 |
}
|
|
1665 |
||
1666 |
return; |
|
1667 |
}
|
|
1668 |
||
1669 |
/**
|
|
1670 |
* Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
|
|
1671 |
*
|
|
1672 |
* @param mixed $lang_set specifies the language entries to include
|
|
1673 |
* @param bool $use_db internal variable for recursion, do not use
|
|
1674 |
* @param bool $use_help internal variable for recursion, do not use
|
|
1675 |
*
|
|
1676 |
* Examples:
|
|
1677 |
* <code>
|
|
1678 |
* $lang_set = array('posting', 'help' => 'faq');
|
|
1679 |
* $lang_set = array('posting', 'viewtopic', 'help' => array('bbcode', 'faq'))
|
|
1680 |
* $lang_set = array(array('posting', 'viewtopic'), 'help' => array('bbcode', 'faq'))
|
|
1681 |
* $lang_set = 'posting'
|
|
1682 |
* $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))
|
|
1683 |
* </code>
|
|
1684 |
*/
|
|
1685 |
function add_lang($lang_set, $use_db = false, $use_help = false) |
|
1686 |
{
|
|
1687 |
global $phpEx; |
|
1688 |
||
1689 |
if (is_array($lang_set)) |
|
1690 |
{
|
|
1691 |
foreach ($lang_set as $key => $lang_file) |
|
1692 |
{
|
|
1693 |
// Please do not delete this line.
|
|
1694 |
// We have to force the type here, else [array] language inclusion will not work
|
|
1695 |
$key = (string) $key; |
|
1696 |
||
1697 |
if ($key == 'db') |
|
1698 |
{
|
|
1699 |
$this->add_lang($lang_file, true, $use_help); |
|
1700 |
}
|
|
1701 |
else if ($key == 'help') |
|
1702 |
{
|
|
1703 |
$this->add_lang($lang_file, $use_db, true); |
|
1704 |
}
|
|
1705 |
else if (!is_array($lang_file)) |
|
1706 |
{
|
|
1707 |
$this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help); |
|
1708 |
}
|
|
1709 |
else
|
|
1710 |
{
|
|
1711 |
$this->add_lang($lang_file, $use_db, $use_help); |
|
1712 |
}
|
|
1713 |
}
|
|
1714 |
unset($lang_set); |
|
1715 |
}
|
|
1716 |
else if ($lang_set) |
|
1717 |
{
|
|
1718 |
$this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help); |
|
1719 |
}
|
|
1720 |
}
|
|
1721 |
||
1722 |
/**
|
|
1723 |
* Set language entry (called by add_lang)
|
|
1724 |
* @access private
|
|
1725 |
*/
|
|
1726 |
function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false) |
|
1727 |
{
|
|
1728 |
global $phpEx; |
|
1729 |
||
1730 |
// Make sure the language path is set (if the user setup did not happen it is not set)
|
|
1731 |
if (!$this->lang_path) |
|
1732 |
{
|
|
1733 |
global $phpbb_root_path, $config; |
|
1734 |
||
1735 |
$this->lang_path = $phpbb_root_path . 'language/' . basename($config['default_lang']) . '/'; |
|
1736 |
}
|
|
1737 |
||
1738 |
// $lang == $this->lang
|
|
1739 |
// $help == $this->help
|
|
1740 |
// - add appropriate variables here, name them as they are used within the language file...
|
|
1741 |
if (!$use_db) |
|
1742 |
{
|
|
1743 |
if ($use_help && strpos($lang_file, '/') !== false) |
|
1744 |
{
|
|
1745 |
$language_filename = $this->lang_path . substr($lang_file, 0, stripos($lang_file, '/') + 1) . 'help_' . substr($lang_file, stripos($lang_file, '/') + 1) . '.' . $phpEx; |
|
1746 |
}
|
|
1747 |
else
|
|
1748 |
{
|
|
1749 |
$language_filename = $this->lang_path . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx; |
|
1750 |
}
|
|
1751 |
||
1752 |
if ((@include $language_filename) === false) |
|
1753 |
{
|
|
1754 |
trigger_error('Language file ' . basename($language_filename) . ' couldn\'t be opened.', E_USER_ERROR); |
|
1755 |
}
|
|
1756 |
}
|
|
1757 |
else if ($use_db) |
|
1758 |
{
|
|
1759 |
// Get Database Language Strings
|
|
1760 |
// Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed
|
|
1761 |
// For example: help:faq, posting
|
|
1762 |
}
|
|
1763 |
}
|
|
1764 |
||
1765 |
/**
|
|
1766 |
* Format user date
|
|
1767 |
*/
|
|
1768 |
function format_date($gmepoch, $format = false, $forcedate = false) |
|
1769 |
{
|
|
1770 |
static $midnight; |
|
1771 |
||
1772 |
$lang_dates = $this->lang['datetime']; |
|
1773 |
$format = (!$format) ? $this->date_format : $format; |
|
1774 |
||
1775 |
// Short representation of month in format
|
|
1776 |
if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false)) |
|
1777 |
{
|
|
1778 |
$lang_dates['May'] = $lang_dates['May_short']; |
|
1779 |
}
|
|
1780 |
||
1781 |
unset($lang_dates['May_short']); |
|
1782 |
||
1783 |
if (!$midnight) |
|
1784 |
{
|
|
1785 |
list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $this->timezone + $this->dst)); |
|
1786 |
$midnight = gmmktime(0, 0, 0, $m, $d, $y) - $this->timezone - $this->dst; |
|
1787 |
}
|
|
1788 |
||
1789 |
if (strpos($format, '|') === false || ($gmepoch < $midnight - 86400 && !$forcedate) || ($gmepoch > $midnight + 172800 && !$forcedate)) |
|
1790 |
{
|
|
1791 |
return strtr(@gmdate(str_replace('|', '', $format), $gmepoch + $this->timezone + $this->dst), $lang_dates); |
|
1792 |
}
|
|
1793 |
||
1794 |
if ($gmepoch > $midnight + 86400 && !$forcedate) |
|
1795 |
{
|
|
1796 |
$format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1); |
|
1797 |
return str_replace('||', $this->lang['datetime']['TOMORROW'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates)); |
|
1798 |
}
|
|
1799 |
else if ($gmepoch > $midnight && !$forcedate) |
|
1800 |
{
|
|
1801 |
$format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1); |
|
1802 |
return str_replace('||', $this->lang['datetime']['TODAY'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates)); |
|
1803 |
}
|
|
1804 |
else if ($gmepoch > $midnight - 86400 && !$forcedate) |
|
1805 |
{
|
|
1806 |
$format = substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1); |
|
1807 |
return str_replace('||', $this->lang['datetime']['YESTERDAY'], strtr(@gmdate($format, $gmepoch + $this->timezone + $this->dst), $lang_dates)); |
|
1808 |
}
|
|
1809 |
||
1810 |
return strtr(@gmdate(str_replace('|', '', $format), $gmepoch + $this->timezone + $this->dst), $lang_dates); |
|
1811 |
}
|
|
1812 |
||
1813 |
/**
|
|
1814 |
* Get language id currently used by the user
|
|
1815 |
*/
|
|
1816 |
function get_iso_lang_id() |
|
1817 |
{
|
|
1818 |
global $config, $db; |
|
1819 |
||
1820 |
if (!empty($this->lang_id)) |
|
1821 |
{
|
|
1822 |
return $this->lang_id; |
|
1823 |
}
|
|
1824 |
||
1825 |
if (!$this->lang_name) |
|
1826 |
{
|
|
1827 |
$this->lang_name = $config['default_lang']; |
|
1828 |
}
|
|
1829 |
||
1830 |
$sql = 'SELECT lang_id |
|
1831 |
FROM ' . LANG_TABLE . " |
|
1832 |
WHERE lang_iso = '" . $db->sql_escape($this->lang_name) . "'"; |
|
1833 |
$result = $db->sql_query($sql); |
|
1834 |
$this->lang_id = (int) $db->sql_fetchfield('lang_id'); |
|
1835 |
$db->sql_freeresult($result); |
|
1836 |
||
1837 |
return $this->lang_id; |
|
1838 |
}
|
|
1839 |
||
1840 |
/**
|
|
1841 |
* Get users profile fields
|
|
1842 |
*/
|
|
1843 |
function get_profile_fields($user_id) |
|
1844 |
{
|
|
1845 |
global $db; |
|
1846 |
||
1847 |
if (isset($this->profile_fields)) |
|
1848 |
{
|
|
1849 |
return; |
|
1850 |
}
|
|
1851 |
||
1852 |
$sql = 'SELECT * |
|
1853 |
FROM ' . PROFILE_FIELDS_DATA_TABLE . " |
|
1854 |
WHERE user_id = $user_id"; |
|
1855 |
$result = $db->sql_query_limit($sql, 1); |
|
1856 |
$this->profile_fields = (!($row = $db->sql_fetchrow($result))) ? array() : $row; |
|
1857 |
$db->sql_freeresult($result); |
|
1858 |
}
|
|
1859 |
||
1860 |
/**
|
|
1861 |
* Specify/Get image
|
|
1862 |
*/
|
|
1863 |
function img($img, $alt = '', $width = false, $suffix = '', $type = 'full_tag') |
|
1864 |
{
|
|
1865 |
static $imgs; |
|
1866 |
global $phpbb_root_path; |
|
1867 |
||
1868 |
$img_data = &$imgs[$img]; |
|
1869 |
||
1870 |
if (empty($img_data)) |
|
1871 |
{
|
|
1872 |
if (!isset($this->img_array[$img])) |
|
1873 |
{
|
|
1874 |
// Do not fill the image to let designers decide what to do if the image is empty
|
|
1875 |
$img_data = ''; |
|
1876 |
return $img_data; |
|
1877 |
}
|
|
1878 |
||
1879 |
$img_data['src'] = $phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename']; |
|
1880 |
$img_data['width'] = $this->img_array[$img]['image_width']; |
|
1881 |
$img_data['height'] = $this->img_array[$img]['image_height']; |
|
1882 |
}
|
|
1883 |
||
1884 |
$alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt; |
|
1885 |
||
1886 |
switch ($type) |
|
1887 |
{
|
|
1888 |
case 'src': |
|
1889 |
return $img_data['src']; |
|
1890 |
break; |
|
1891 |
||
1892 |
case 'width': |
|
1893 |
return ($width === false) ? $img_data['width'] : $width; |
|
1894 |
break; |
|
1895 |
||
1896 |
case 'height': |
|
1897 |
return $img_data['height']; |
|
1898 |
break; |
|
1899 |
||
1900 |
default: |
|
1901 |
$use_width = ($width === false) ? $img_data['width'] : $width; |
|
1902 |
||
1903 |
return '<img src="' . $img_data['src'] . '"' . (($use_width) ? ' width="' . $use_width . '"' : '') . (($img_data['height']) ? ' height="' . $img_data['height'] . '"' : '') . ' alt="' . $alt . '" title="' . $alt . '" />'; |
|
1904 |
break; |
|
1905 |
}
|
|
1906 |
}
|
|
1907 |
||
1908 |
/**
|
|
1909 |
* Get option bit field from user options
|
|
1910 |
*/
|
|
1911 |
function optionget($key, $data = false) |
|
1912 |
{
|
|
1913 |
if (!isset($this->keyvalues[$key])) |
|
1914 |
{
|
|
1915 |
$var = ($data) ? $data : $this->data['user_options']; |
|
1916 |
$this->keyvalues[$key] = ($var & 1 << $this->keyoptions[$key]) ? true : false; |
|
1917 |
}
|
|
1918 |
||
1919 |
return $this->keyvalues[$key]; |
|
1920 |
}
|
|
1921 |
||
1922 |
/**
|
|
1923 |
* Set option bit field for user options
|
|
1924 |
*/
|
|
1925 |
function optionset($key, $value, $data = false) |
|
1926 |
{
|
|
1927 |
$var = ($data) ? $data : $this->data['user_options']; |
|
1928 |
||
1929 |
if ($value && !($var & 1 << $this->keyoptions[$key])) |
|
1930 |
{
|
|
1931 |
$var += 1 << $this->keyoptions[$key]; |
|
1932 |
}
|
|
1933 |
else if (!$value && ($var & 1 << $this->keyoptions[$key])) |
|
1934 |
{
|
|
1935 |
$var -= 1 << $this->keyoptions[$key]; |
|
1936 |
}
|
|
1937 |
else
|
|
1938 |
{
|
|
1939 |
return ($data) ? $var : false; |
|
1940 |
}
|
|
1941 |
||
1942 |
if (!$data) |
|
1943 |
{
|
|
1944 |
$this->data['user_options'] = $var; |
|
1945 |
return true; |
|
1946 |
}
|
|
1947 |
else
|
|
1948 |
{
|
|
1949 |
return $var; |
|
1950 |
}
|
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
1951 |
}
|
1952 |
||
1953 |
/** IVLE AUTH
|
|
1954 |
* This function attempts to authenticate from a signed cookie provided by
|
|
1955 |
* IVLE. If it does it will return either the forum user_id for the logged in
|
|
1956 |
* IVLE user or will create a new one on-the-fly.
|
|
1957 |
*
|
|
1958 |
* If a bad authentication is given then the ANONAMOUS user will be returned
|
|
1959 |
*/
|
|
1960 |
function ivle_auth() |
|
1961 |
{
|
|
1962 |
global $db, $phpEx; |
|
1963 |
||
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
1964 |
// Get the shared secret between IVLE and the Forum
|
1965 |
require($phpbb_root_path . 'config.' . $phpEx); |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
1966 |
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
1967 |
// Shared Cookie
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
1968 |
$ivle_cookie = explode(':',$_COOKIE['ivleforumcookie']); |
1969 |
||
1970 |
if ($ivle_cookie == "NONE") { |
|
1971 |
return ANONYMOUS; |
|
1972 |
}
|
|
1973 |
||
1974 |
// Decode and unescape the Cookie contents
|
|
1975 |
$ivle_uid = urldecode($ivle_cookie[0]); |
|
1976 |
$ivle_nick = urldecode($ivle_cookie[1]); |
|
1977 |
$ivle_email = urldecode($ivle_cookie[2]); |
|
1978 |
$ivle_role = urldecode($ivle_cookie[3]); |
|
1979 |
$ivle_hash = $ivle_cookie[4]; |
|
1980 |
||
1981 |
// Check if uid + nick + email + secret is the same as the hash
|
|
1982 |
//$ivle_auth = False; // Flag just incase anything else need to know
|
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
1983 |
if(md5($ivle_cookie[0].$ivle_cookie[1].$ivle_cookie[2].$ivle_cookie[3].$forum_secret) |
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
1984 |
== $ivle_hash) { |
1985 |
//$ivle_auth = True;
|
|
1986 |
||
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
1987 |
// Check if the user exists in the database
|
1988 |
$sql = 'SELECT user_id |
|
1989 |
FROM ' . USERS_TABLE . " |
|
1990 |
WHERE username = '" . $db->sql_escape($ivle_uid) . "';"; |
|
1991 |
$result = $db->sql_query($sql); |
|
1992 |
$row = $db->sql_fetchrow($result); |
|
1993 |
$user_id = $row['user_id']; |
|
1994 |
$db->sql_freeresult($result); |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
1995 |
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
1996 |
// If no user_id is found for the username, create a new user
|
1997 |
if(!$user_id) { |
|
1998 |
// Needed for IVLE auth overide
|
|
1999 |
include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2000 |
|
2001 |
// Add all users to the Registered Group
|
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
2002 |
$sql = 'SELECT group_id |
2003 |
FROM ' . GROUPS_TABLE . " |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2004 |
WHERE group_name = '" . $db->sql_escape('REGISTERED') . "' |
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
2005 |
AND group_type = " . GROUP_SPECIAL; |
2006 |
$result = $db->sql_query($sql); |
|
2007 |
$row = $db->sql_fetchrow($result); |
|
2008 |
$db->sql_freeresult($result); |
|
2009 |
if (!$row) { |
|
2010 |
trigger_error('NO_GROUP'); |
|
2011 |
}
|
|
2012 |
||
2013 |
$group_id = $row['group_id']; |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2014 |
|
2015 |
// Get the Time and Timezone
|
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
2016 |
$timezone = date('Z') / 3600; |
2017 |
$is_dst = date('I'); |
|
2018 |
$timezone = ($is_dst) ? $timezone - 1 : $timezone; |
|
2019 |
||
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2020 |
// Fill into array
|
2021 |
$user_row = array( |
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
2022 |
'username' => $ivle_uid, |
2023 |
'user_password' => '', # Not a valid hash |
|
2024 |
'user_email' => $ivle_email, |
|
2025 |
'group_id' => (int) $group_id, |
|
2026 |
'user_timezone' => (float) $timezone, |
|
2027 |
'user_dst' => $is_dst, |
|
2028 |
'user_lang' => 'en', |
|
2029 |
'user_type' => USER_NORMAL, |
|
2030 |
'user_actkey' => '', |
|
2031 |
'user_ip' => $this->ip, |
|
2032 |
'user_regdate' => time(), |
|
2033 |
'user_inactive_reason' => 0, |
|
2034 |
'user_inactive_time' => 0, |
|
2035 |
);
|
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2036 |
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
2037 |
// Add user
|
2038 |
$user_id = user_add($user_row); |
|
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2039 |
|
2040 |
// Add any aditional groups
|
|
2041 |
// Select the equvialent group
|
|
2042 |
$group = False; |
|
2043 |
switch($ivle_role) { |
|
2044 |
case('admin'): |
|
2045 |
$group = 'ADMINISTRATORS'; |
|
2046 |
break; |
|
2047 |
case('lecturer'): |
|
2048 |
$group = 'GLOBAL_MODERATORS'; |
|
2049 |
break; |
|
2050 |
}
|
|
2051 |
if ($group) { |
|
2052 |
// Find the group_id
|
|
2053 |
$sql = 'SELECT group_id |
|
671
by dcoles
forum: Now uses a unique secret generated at './setup config' time for shared secret |
2054 |
FROM ' . GROUPS_TABLE . " |
2055 |
WHERE group_name = '" . $db->sql_escape($group) . "' |
|
2056 |
AND group_type = " . GROUP_SPECIAL; |
|
2057 |
||
493
by dcoles
session.php: More interfaceing between IVLE and phpBB. Adds groups, emails and |
2058 |
$result = $db->sql_query($sql); |
2059 |
$row = $db->sql_fetchrow($result); |
|
2060 |
$db->sql_freeresult($result); |
|
2061 |
||
2062 |
if (!$row) { |
|
2063 |
trigger_error('NO_GROUP'); |
|
2064 |
}
|
|
2065 |
||
2066 |
$group_id = $row['group_id']; |
|
2067 |
||
2068 |
group_user_add($group_id,Array($user_id)); |
|
2069 |
}
|
|
2070 |
}
|
|
2071 |
return $user_id; |
|
2072 |
} else { |
|
2073 |
return False; |
|
2074 |
}
|
|
2075 |
}
|
|
443
by dcoles
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0 |
2076 |
}
|
461
by dcoles
Added Auth bridge between IVLE and phpBB using shared cookie |
2077 |
?>
|