~azzar1/unity/add-show-desktop-key

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: file.php,v 1.5 2007/11/17 22:35:33 kellanved 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
define('IN_PHPBB', true);
15
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../';
16
$phpEx = substr(strrchr(__FILE__, '.'), 1);
17
18
if (isset($_GET['avatar']))
19
{
20
	require($phpbb_root_path . 'config.' . $phpEx);
21
	require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx);
22
	require($phpbb_root_path . 'includes/cache.' . $phpEx);
23
	require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
24
	require($phpbb_root_path . 'includes/constants.' . $phpEx);
25
26
	$db = new $sql_db();
27
	$cache = new cache();
28
29
	// Connect to DB
30
	if (!@$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false))
31
	{
32
		exit;
33
	}
34
	unset($dbpasswd);
35
	
36
	// worst-case default
37
	$browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : 'msie 6.0';
38
39
	$config = $cache->obtain_config();
40
	$filename = $_GET['avatar'];
41
	$avatar_group = false;
42
	if ($filename[0] === 'g')
43
	{
44
		$avatar_group = true;
45
		$filename = substr($filename, 1);
46
	}
47
	
48
	// '==' is not a bug - . as the first char is as bad as no dot at all
49
	if (strpos($filename, '.') == false)
50
	{
51
		header('HTTP/1.0 403 forbidden');
52
		if (!empty($cache))
53
		{
54
			$cache->unload();
55
		}
56
		$db->sql_close();
57
		exit;
58
	}
59
	
60
	$ext		= substr(strrchr($filename, '.'), 1);
61
	$stamp		= (int) substr(stristr($filename, '_'), 1);
62
	$filename	= (int) $filename;
63
	
64
	// let's see if we have to send the file at all
65
	$last_load 	=  isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime(trim($_SERVER['HTTP_IF_MODIFIED_SINCE'])) : false;
66
	if (strpos(strtolower($browser), 'msie 6.0') === false)
67
	{
68
		if ($last_load !== false && $last_load <= $stamp)
69
		{
70
			header('Not Modified', true, 304);
71
			// seems that we need those too ... browsers
72
			header('Pragma: public');
73
			header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
74
			exit();
75
		} 
76
		else
77
		{
78
			header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stamp) . ' GMT');
79
		}
80
	}
81
	
82
	if (!in_array($ext, array('png', 'gif', 'jpg', 'jpeg')))
83
	{
84
		// no way such an avatar could exist. They are not following the rules, stop the show.
85
		header("HTTP/1.0 403 forbidden");
86
		if (!empty($cache))
87
		{
88
			$cache->unload();
89
		}
90
		$db->sql_close();
91
		exit;
92
	}
93
	
94
	if (!$filename)
95
	{
96
		// no way such an avatar could exist. They are not following the rules, stop the show.
97
		header("HTTP/1.0 403 forbidden");
98
		if (!empty($cache))
99
		{
100
			$cache->unload();
101
		}
102
		$db->sql_close();
103
		exit;
104
	}
105
106
	send_avatar_to_browser(($avatar_group ? 'g' : '') . $filename . '.' . $ext, $browser);
107
108
	if (!empty($cache))
109
	{
110
		$cache->unload();
111
	}
112
	$db->sql_close();
113
	exit;
114
}
115
116
// implicit else: we are not in avatar mode
117
include($phpbb_root_path . 'common.' . $phpEx);
118
119
$download_id = request_var('id', 0);
120
$mode = request_var('mode', '');
121
$thumbnail = request_var('t', false);
122
123
// Start session management, do not update session page.
124
$user->session_begin(false);
125
$auth->acl($user->data);
126
$user->setup('viewtopic');
127
128
if (!$download_id)
129
{
130
	trigger_error('NO_ATTACHMENT_SELECTED');
131
}
132
133
if (!$config['allow_attachments'] && !$config['allow_pm_attach'])
134
{
135
	trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');
136
}
137
138
$sql = 'SELECT attach_id, in_message, post_msg_id, extension, is_orphan, poster_id
139
	FROM ' . ATTACHMENTS_TABLE . "
140
	WHERE attach_id = $download_id";
141
$result = $db->sql_query_limit($sql, 1);
142
$attachment = $db->sql_fetchrow($result);
143
$db->sql_freeresult($result);
144
145
if (!$attachment)
146
{
147
	trigger_error('ERROR_NO_ATTACHMENT');
148
}
149
150
if ((!$attachment['in_message'] && !$config['allow_attachments']) || ($attachment['in_message'] && !$config['allow_pm_attach']))
151
{
152
	trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');
153
}
154
155
$row = array();
156
157
if ($attachment['is_orphan'])
158
{
159
	// We allow admins having attachment permissions to see orphan attachments...
160
	$own_attachment = ($auth->acl_get('a_attach') || $attachment['poster_id'] == $user->data['user_id']) ? true : false;
161
162
	if (!$own_attachment || ($attachment['in_message'] && !$auth->acl_get('u_pm_download')) || (!$attachment['in_message'] && !$auth->acl_get('u_download')))
163
	{
164
		trigger_error('ERROR_NO_ATTACHMENT');
165
	}
166
167
	// Obtain all extensions...
168
	$extensions = $cache->obtain_attach_extensions(true);
169
}
170
else
171
{
172
	if (!$attachment['in_message'])
173
	{
174
		//
175
		$sql = 'SELECT p.forum_id, f.forum_password, f.parent_id
176
			FROM ' . POSTS_TABLE . ' p, ' . FORUMS_TABLE . ' f
177
			WHERE p.post_id = ' . $attachment['post_msg_id'] . '
178
				AND p.forum_id = f.forum_id';
179
		$result = $db->sql_query_limit($sql, 1);
180
		$row = $db->sql_fetchrow($result);
181
		$db->sql_freeresult($result);
182
183
		// Global announcement?
184
		$f_download = (!$row) ? $auth->acl_getf_global('f_download') : $auth->acl_get('f_download', $row['forum_id']);
185
186
		if ($auth->acl_get('u_download') && $f_download)
187
		{
188
			if ($row && $row['forum_password'])
189
			{
190
				// Do something else ... ?
191
				login_forum_box($row);
192
			}
193
		}
194
		else
195
		{
196
			trigger_error('SORRY_AUTH_VIEW_ATTACH');
197
		}
198
	}
199
	else
200
	{
201
		$row['forum_id'] = false;
202
		if (!$auth->acl_get('u_pm_download'))
203
		{
204
			trigger_error('SORRY_AUTH_VIEW_ATTACH');
205
		}
206
	}
207
208
	// disallowed?
209
	$extensions = array();
210
	if (!extension_allowed($row['forum_id'], $attachment['extension'], $extensions))
211
	{
212
		trigger_error(sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension']));
213
	}
214
}
215
216
if (!download_allowed())
217
{
218
	trigger_error($user->lang['LINKAGE_FORBIDDEN']);
219
}
220
221
$download_mode = (int) $extensions[$attachment['extension']]['download_mode'];
222
223
// Fetching filename here to prevent sniffing of filename
224
$sql = 'SELECT attach_id, is_orphan, in_message, post_msg_id, extension, physical_filename, real_filename, mimetype
225
	FROM ' . ATTACHMENTS_TABLE . "
226
	WHERE attach_id = $download_id";
227
$result = $db->sql_query_limit($sql, 1);
228
$attachment = $db->sql_fetchrow($result);
229
$db->sql_freeresult($result);
230
231
if (!$attachment)
232
{
233
	trigger_error('ERROR_NO_ATTACHMENT');
234
}
235
236
$attachment['physical_filename'] = basename($attachment['physical_filename']);
237
$display_cat = $extensions[$attachment['extension']]['display_cat'];
238
239
if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg'))
240
{
241
	$display_cat = ATTACHMENT_CATEGORY_NONE;
242
}
243
244
if ($display_cat == ATTACHMENT_CATEGORY_FLASH && !$user->optionget('viewflash'))
245
{
246
	$display_cat = ATTACHMENT_CATEGORY_NONE;
247
}
248
249
if ($thumbnail)
250
{
251
	$attachment['physical_filename'] = 'thumb_' . $attachment['physical_filename'];
252
}
253
else if (($display_cat == ATTACHMENT_CATEGORY_NONE || $display_cat == ATTACHMENT_CATEGORY_IMAGE) && !$attachment['is_orphan'])
254
{
255
	// Update download count
256
	$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
257
		SET download_count = download_count + 1
258
		WHERE attach_id = ' . $attachment['attach_id'];
259
	$db->sql_query($sql);
260
}
261
262
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && strpos(strtolower($user->browser), 'msie') !== false)
263
{
264
	wrap_img_in_html(append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'id=' . $attachment['attach_id']), $attachment['real_filename']);
265
}
266
else
267
{
268
	// Determine the 'presenting'-method
269
	if ($download_mode == PHYSICAL_LINK)
270
	{
271
		// This presenting method should no longer be used
272
		if (!@is_dir($phpbb_root_path . $config['upload_path']))
273
		{
274
			trigger_error($user->lang['PHYSICAL_DOWNLOAD_NOT_POSSIBLE']);
275
		}
276
		
277
		redirect($phpbb_root_path . $config['upload_path'] . '/' . $attachment['physical_filename']);
278
		exit;
279
	}
280
	else
281
	{
282
		send_file_to_browser($attachment, $config['upload_path'], $display_cat);
283
		exit;
284
	}
285
}
286
287
288
/**
289
* A simplified function to deliver avatars
290
* The argument needs to be checked before calling this function.
291
*/
292
function send_avatar_to_browser($file, $browser)
293
{
294
	global $config, $phpbb_root_path;
295
296
	$prefix = $config['avatar_salt'] . '_';
297
	$image_dir = $config['avatar_path'];
298
299
	// Adjust image_dir path (no trailing slash)
300
	if (substr($image_dir, -1, 1) == '/' || substr($image_dir, -1, 1) == '\\')
301
	{
302
		$image_dir = substr($image_dir, 0, -1) . '/';
303
	}
304
	$image_dir = str_replace(array('../', '..\\', './', '.\\'), '', $image_dir);
305
306
	if ($image_dir && ($image_dir[0] == '/' || $image_dir[0] == '\\'))
307
	{
308
		$image_dir = '';
309
	}
310
	$file_path = $phpbb_root_path . $image_dir . '/' . $prefix . $file;
311
312
	if ((@file_exists($file_path) && @is_readable($file_path)) && !headers_sent())
313
	{
314
		header('Pragma: public');
315
316
		$image_data = @getimagesize($file_path);
317
		header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
318
319
		if (strpos(strtolower($browser), 'msie') !== false)
320
		{
321
			header('Content-Disposition: attachment; ' . header_filename($file));
322
323
			if (strpos(strtolower($browser), 'msie 6.0') !== false)
324
			{
325
				header('Expires: -1');
326
			}
327
			else
328
			{
329
				header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
330
			}
331
		}
332
		else
333
		{
334
			header('Content-Disposition: inline; ' . header_filename($file));
335
			header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
336
		}
337
338
		$size = @filesize($file_path);
339
		if ($size)
340
		{
341
			header("Content-Length: $size");
342
		}
343
344
		if (@readfile($file_path) === false)
345
		{
346
			$fp = @fopen($file_path, 'rb');
347
348
			if ($fp !== false)
349
			{
350
				while (!feof($fp))
351
				{
352
					echo fread($fp, 8192);
353
				}
354
				fclose($fp);
355
			}
356
		}
357
358
		flush();
359
	}
360
	else
361
	{
362
		header('HTTP/1.0 404 not found');
363
	}
364
}
365
366
/**
367
* Wraps an url into a simple html page. Used to display attachments in IE.
368
* this is a workaround for now; might be moved to template system later
369
* direct any complaints to 1 Microsoft Way, Redmond
370
*/
371
function wrap_img_in_html($src, $title)
372
{
373
	echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-Strict.dtd">';
374
	echo '<html>';
375
	echo '<head>';
376
	echo '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />';
377
	echo '<title>' . $title . '</title>';
378
	echo '</head>';
379
	echo '<body>';
380
	echo '<div>';
381
	echo '<img src="' . $src . '" alt="' . $title . '" />';
382
	echo '</div>';
383
	echo '</body>';
384
	echo '</html>';
385
}
386
387
/**
388
* Send file to browser
389
*/
390
function send_file_to_browser($attachment, $upload_dir, $category)
391
{
392
	global $user, $db, $config, $phpbb_root_path;
393
394
	$filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
395
396
	if (!@file_exists($filename))
397
	{
398
		trigger_error($user->lang['ERROR_NO_ATTACHMENT'] . '<br /><br />' . sprintf($user->lang['FILE_NOT_FOUND_404'], $filename));
399
	}
400
401
	// Correct the mime type - we force application/octetstream for all files, except images
402
	// Please do not change this, it is a security precaution
403
	if ($category != ATTACHMENT_CATEGORY_IMAGE || strpos($attachment['mimetype'], 'image') !== 0)
404
	{
405
		$attachment['mimetype'] = (strpos(strtolower($user->browser), 'msie') !== false || strpos(strtolower($user->browser), 'opera') !== false) ? 'application/octetstream' : 'application/octet-stream';
406
	}
407
408
	if (@ob_get_length())
409
	{
410
		@ob_end_clean();
411
	}
412
413
	// Now send the File Contents to the Browser
414
	$size = @filesize($filename);
415
416
	// To correctly display further errors we need to make sure we are using the correct headers for both (unsetting content-length may not work)
417
418
	// Check if headers already sent or not able to get the file contents.
419
	if (headers_sent() || !@file_exists($filename) || !@is_readable($filename))
420
	{
421
		// PHP track_errors setting On?
422
		if (!empty($php_errormsg))
423
		{
424
			trigger_error($user->lang['UNABLE_TO_DELIVER_FILE'] . '<br />' . sprintf($user->lang['TRACKED_PHP_ERROR'], $php_errormsg));
425
		}
426
427
		trigger_error('UNABLE_TO_DELIVER_FILE');
428
	}
429
430
	// Now the tricky part... let's dance
431
	header('Pragma: public');
432
433
	/**
434
	* Commented out X-Sendfile support. To not expose the physical filename within the header if xsendfile is absent we need to look into methods of checking it's status.
435
	*
436
	* Try X-Sendfile since it is much more server friendly - only works if the path is *not* outside of the root path...
437
	* lighttpd has core support for it. An apache2 module is available at http://celebnamer.celebworld.ws/stuff/mod_xsendfile/
438
	*
439
	* Not really ideal, but should work fine...
440
	* <code>
441
	*	if (strpos($upload_dir, '/') !== 0 && strpos($upload_dir, '../') === false)
442
	*	{
443
	*		header('X-Sendfile: ' . $filename);
444
	*	}
445
	* </code>
446
	*/
447
448
	// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.
449
	header('Content-Type: ' . $attachment['mimetype']);
450
451
	if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie') !== false))
452
	{
453
		header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
454
		if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))
455
		{
456
			header('expires: -1');
457
		}
458
	}
459
	else
460
	{
461
		header('Content-Disposition: ' . ((strpos($attachment['mimetype'], 'image') === 0) ? 'inline' : 'attachment') . '; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));
462
	}
463
	
464
	if ($size)
465
	{
466
		header("Content-Length: $size");
467
	}
468
469
	// Try to deliver in chunks
470
	@set_time_limit(0);
471
472
	$fp = @fopen($filename, 'rb');
473
474
	if ($fp !== false)
475
	{
476
		while (!feof($fp))
477
		{
478
			echo fread($fp, 8192);
479
		}
480
		fclose($fp);
481
	}
482
	else
483
	{
484
		@readfile($filename);
485
	}
486
487
	flush();
488
	exit;
489
}
490
491
/**
492
* Get a browser friendly UTF-8 encoded filename
493
*/
494
function header_filename($file)
495
{
496
	$user_agent = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
497
498
	// There be dragons here.
499
	// Not many follows the RFC...
500
	if (strpos($user_agent, 'MSIE') !== false || strpos($user_agent, 'Safari') !== false || strpos($user_agent, 'Konqueror') !== false)
501
	{
502
		return "filename=" . rawurlencode($file);
503
	}
504
505
	// follow the RFC for extended filename for the rest
506
	return "filename*=UTF-8''" . rawurlencode($file);
507
}
508
509
/**
510
* Check if downloading item is allowed
511
*/
512
function download_allowed()
513
{
514
	global $config, $user, $db;
515
516
	if (!$config['secure_downloads'])
517
	{
518
		return true;
519
	}
520
521
	$url = (!empty($_SERVER['HTTP_REFERER'])) ? trim($_SERVER['HTTP_REFERER']) : trim(getenv('HTTP_REFERER'));
522
523
	if (!$url)
524
	{
525
		return ($config['secure_allow_empty_referer']) ? true : false;
526
	}
527
528
	// Split URL into domain and script part
529
	$url = @parse_url($url);
530
531
	if ($url === false)
532
	{
533
		return ($config['secure_allow_empty_referer']) ? true : false;
534
	}
535
536
	$hostname = $url['host'];
537
	unset($url);
538
539
	$allowed = ($config['secure_allow_deny']) ? false : true;
540
	$iplist = array();
541
542
	if (($ip_ary = @gethostbynamel($hostname)) !== false)
543
	{
544
		foreach ($ip_ary as $ip)
545
		{
546
			if ($ip)
547
			{
548
				$iplist[] = $ip;
549
			}
550
		}
551
	}
552
	
553
	// Check for own server...
554
	$server_name = (!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME');
555
556
	// Forcing server vars is the only way to specify/override the protocol
557
	if ($config['force_server_vars'] || !$server_name)
558
	{
559
		$server_name = $config['server_name'];
560
	}
561
562
	if (preg_match('#^.*?' . preg_quote($server_name, '#') . '.*?$#i', $hostname))
563
	{
564
		$allowed = true;
565
	}
566
	
567
	// Get IP's and Hostnames
568
	if (!$allowed)
569
	{
570
		$sql = 'SELECT site_ip, site_hostname, ip_exclude
571
			FROM ' . SITELIST_TABLE;
572
		$result = $db->sql_query($sql);
573
574
		while ($row = $db->sql_fetchrow($result))
575
		{
576
			$site_ip = trim($row['site_ip']);
577
			$site_hostname = trim($row['site_hostname']);
578
579
			if ($site_ip)
580
			{
581
				foreach ($iplist as $ip)
582
				{
583
					if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($site_ip, '#')) . '$#i', $ip))
584
					{
585
						if ($row['ip_exclude'])
586
						{
587
							$allowed = ($config['secure_allow_deny']) ? false : true;
588
							break 2;
589
						}
590
						else
591
						{
592
							$allowed = ($config['secure_allow_deny']) ? true : false;
593
						}
594
					}
595
				}
596
			}
597
598
			if ($site_hostname)
599
			{
600
				if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($site_hostname, '#')) . '$#i', $hostname))
601
				{
602
					if ($row['ip_exclude'])
603
					{
604
						$allowed = ($config['secure_allow_deny']) ? false : true;
605
						break;
606
					}
607
					else
608
					{
609
						$allowed = ($config['secure_allow_deny']) ? true : false;
610
					}
611
				}
612
			}
613
		}
614
		$db->sql_freeresult($result);
615
	}
616
	
617
	return $allowed;
618
}
619
620
?>