Register
phpBB.com Wiki · Home Projects Help

root / tags / milestone_3 / phpBB / download.php

1 3807 acydburn
<?php
2 5114 acydburn
/**
3 5114 acydburn
*
4 5114 acydburn
* @package phpBB3
5 5114 acydburn
* @version $Id$
6 5114 acydburn
* @copyright (c) 2005 phpBB Group
7 5114 acydburn
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8 5114 acydburn
*
9 5114 acydburn
*/
10 3807 acydburn
11 5114 acydburn
/**
12 5114 acydburn
*/
13 3807 acydburn
define('IN_PHPBB', true);
14 3807 acydburn
$phpbb_root_path = './';
15 4473 psotfx
$phpEx = substr(strrchr(__FILE__, '.'), 1);
16 3807 acydburn
include($phpbb_root_path . 'common.'.$phpEx);
17 3807 acydburn
18 4612 acydburn
$download_id = request_var('id', 0);
19 3807 acydburn
20 4844 acydburn
// Thumbnails are not handled by this file by default - but for modders this should be interesting. ;)
21 4844 acydburn
$thumbnail = request_var('t', false);
22 4844 acydburn
23 3807 acydburn
// Start session management
24 5247 acydburn
$user->session_begin();
25 3807 acydburn
$auth->acl($user->data);
26 4844 acydburn
$user->setup('viewtopic');
27 3807 acydburn
28 4055 acydburn
if (!$download_id)
29 3807 acydburn
{
30 3807 acydburn
	trigger_error('NO_ATTACHMENT_SELECTED');
31 3807 acydburn
}
32 3807 acydburn
33 4883 acydburn
if (!$config['allow_attachments'] && !$config['allow_pm_attach'])
34 3807 acydburn
{
35 3807 acydburn
	trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');
36 3807 acydburn
}
37 4612 acydburn
38 5032 acydburn
$sql = 'SELECT attach_id, in_message, post_msg_id, extension
39 4637 acydburn
	FROM ' . ATTACHMENTS_TABLE . "
40 4140 acydburn
	WHERE attach_id = $download_id";
41 4612 acydburn
$result = $db->sql_query_limit($sql, 1);
42 3807 acydburn
43 3969 psotfx
if (!($attachment = $db->sql_fetchrow($result)))
44 3807 acydburn
{
45 3807 acydburn
	trigger_error('ERROR_NO_ATTACHMENT');
46 3807 acydburn
}
47 4612 acydburn
$db->sql_freeresult($result);
48 3807 acydburn
49 4883 acydburn
if ((!$attachment['in_message'] && !$config['allow_attachments']) || ($attachment['in_message'] && !$config['allow_pm_attach']))
50 4883 acydburn
{
51 4883 acydburn
	trigger_error('ATTACHMENT_FUNCTIONALITY_DISABLED');
52 4883 acydburn
}
53 3807 acydburn
54 4883 acydburn
$row = array();
55 4883 acydburn
if (!$attachment['in_message'])
56 3807 acydburn
{
57 4883 acydburn
	//
58 4883 acydburn
	$sql = 'SELECT p.forum_id, f.forum_password, f.parent_id
59 4883 acydburn
		FROM ' . POSTS_TABLE . ' p, ' . FORUMS_TABLE . ' f
60 4883 acydburn
		WHERE p.post_id = ' . $attachment['post_msg_id'] . '
61 4883 acydburn
			AND p.forum_id = f.forum_id';
62 4883 acydburn
	$result = $db->sql_query_limit($sql, 1);
63 4883 acydburn
	$row = $db->sql_fetchrow($result);
64 4883 acydburn
	$db->sql_freeresult($result);
65 4883 acydburn
66 4883 acydburn
	if ($auth->acl_gets('f_download', 'u_download', $row['forum_id']))
67 3807 acydburn
	{
68 4883 acydburn
		if ($row['forum_password'])
69 4883 acydburn
		{
70 4883 acydburn
			// Do something else ... ?
71 4883 acydburn
			login_forum_box($row);
72 4883 acydburn
		}
73 3807 acydburn
	}
74 4883 acydburn
	else
75 4883 acydburn
	{
76 4883 acydburn
		trigger_error('SORRY_AUTH_VIEW_ATTACH');
77 4883 acydburn
	}
78 3807 acydburn
}
79 4637 acydburn
else
80 3807 acydburn
{
81 4883 acydburn
	$row['forum_id'] = 0;
82 4883 acydburn
	if (!$auth->acl_get('u_pm_download') || !$config['auth_download_pm'])
83 4883 acydburn
	{
84 4883 acydburn
		trigger_error('SORRY_AUTH_VIEW_ATTACH');
85 4883 acydburn
	}
86 3807 acydburn
}
87 3807 acydburn
88 3807 acydburn
// disallowed ?
89 4986 acydburn
$extensions = array();
90 4986 acydburn
if (!extension_allowed($row['forum_id'], $attachment['extension'], $extensions))
91 3807 acydburn
{
92 4612 acydburn
	trigger_error(sprintf($user->lang['EXTENSION_DISABLED_AFTER_POSTING'], $attachment['extension']));
93 3807 acydburn
}
94 3807 acydburn
95 4682 acydburn
if (!download_allowed())
96 4682 acydburn
{
97 4682 acydburn
	trigger_error($user->lang['LINKAGE_FORBIDDEN']);
98 4682 acydburn
}
99 4682 acydburn
100 4612 acydburn
$download_mode = (int) $extensions[$attachment['extension']]['download_mode'];
101 3807 acydburn
102 5032 acydburn
// Fetching filename here to prevent sniffing of filename
103 5032 acydburn
$sql = 'SELECT attach_id, in_message, post_msg_id, extension, physical_filename, real_filename, mimetype
104 5032 acydburn
	FROM ' . ATTACHMENTS_TABLE . "
105 5032 acydburn
	WHERE attach_id = $download_id";
106 5032 acydburn
$result = $db->sql_query_limit($sql, 1);
107 5032 acydburn
108 5032 acydburn
if (!($attachment = $db->sql_fetchrow($result)))
109 5032 acydburn
{
110 5032 acydburn
	trigger_error('ERROR_NO_ATTACHMENT');
111 5032 acydburn
}
112 5032 acydburn
$db->sql_freeresult($result);
113 5032 acydburn
114 5032 acydburn
$attachment['physical_filename'] = basename($attachment['physical_filename']);
115 5032 acydburn
116 3807 acydburn
if ($thumbnail)
117 3807 acydburn
{
118 4668 acydburn
	$attachment['physical_filename'] = 'thumb_' . $attachment['physical_filename'];
119 3807 acydburn
}
120 4612 acydburn
else
121 3807 acydburn
{
122 4612 acydburn
	// Update download count
123 4637 acydburn
	$sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
124 3807 acydburn
		SET download_count = download_count + 1
125 3807 acydburn
		WHERE attach_id = ' . $attachment['attach_id'];
126 3807 acydburn
	$db->sql_query($sql);
127 3807 acydburn
}
128 3807 acydburn
129 3807 acydburn
// Determine the 'presenting'-method
130 3807 acydburn
if ($download_mode == PHYSICAL_LINK)
131 3807 acydburn
{
132 5108 acydburn
	if (!@is_dir($phpbb_root_path . $config['upload_path']))
133 3807 acydburn
	{
134 4055 acydburn
		trigger_error($user->lang['PHYSICAL_DOWNLOAD_NOT_POSSIBLE']);
135 3807 acydburn
	}
136 3807 acydburn
137 5108 acydburn
	redirect($phpbb_root_path . $config['upload_path'] . '/' . $attachment['physical_filename']);
138 3807 acydburn
}
139 3807 acydburn
else
140 3807 acydburn
{
141 5108 acydburn
	send_file_to_browser($attachment, $config['upload_path'], $extensions[$attachment['extension']]['display_cat']);
142 4229 acydburn
	exit;
143 3807 acydburn
}
144 3807 acydburn
145 4473 psotfx
146 5114 acydburn
/**
147 5114 acydburn
* Send file to browser
148 5114 acydburn
*/
149 4473 psotfx
function send_file_to_browser($attachment, $upload_dir, $category)
150 4473 psotfx
{
151 5032 acydburn
	global $user, $db, $config, $phpbb_root_path;
152 4473 psotfx
153 5032 acydburn
	$filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
154 4473 psotfx
155 4612 acydburn
	if (!@file_exists($filename))
156 4473 psotfx
	{
157 4473 psotfx
		trigger_error($user->lang['ERROR_NO_ATTACHMENT'] . '<br /><br />' . sprintf($user->lang['FILE_NOT_FOUND_404'], $filename));
158 4473 psotfx
	}
159 4473 psotfx
160 4473 psotfx
	// Determine the Browser the User is using, because of some nasty incompatibilities.
161 4473 psotfx
	// borrowed from phpMyAdmin. :)
162 5032 acydburn
	$user_agent = (!empty($_SERVER['HTTP_USER_AGENT'])) ? $_SERVER['HTTP_USER_AGENT'] : '';
163 4473 psotfx
164 4612 acydburn
	if (ereg('Opera(/| )([0-9].[0-9]{1,2})', $user_agent, $log_version))
165 4473 psotfx
	{
166 4473 psotfx
		$browser_version = $log_version[2];
167 4473 psotfx
		$browser_agent = 'opera';
168 4612 acydburn
	}
169 4612 acydburn
	else if (ereg('MSIE ([0-9].[0-9]{1,2})', $user_agent, $log_version))
170 4473 psotfx
	{
171 4473 psotfx
		$browser_version = $log_version[1];
172 4473 psotfx
		$browser_agent = 'ie';
173 4612 acydburn
	}
174 4612 acydburn
	else if (ereg('OmniWeb/([0-9].[0-9]{1,2})', $user_agent, $log_version))
175 4473 psotfx
	{
176 4473 psotfx
		$browser_version = $log_version[1];
177 4473 psotfx
		$browser_agent = 'omniweb';
178 5114 acydburn
	}
179 4612 acydburn
	else if (ereg('(Konqueror/)(.*)(;)', $user_agent, $log_version))
180 4473 psotfx
	{
181 4612 acydburn
		$browser_version = $log_version[2];
182 4612 acydburn
		$browser_agent = 'konqueror';
183 5114 acydburn
	}
184 4612 acydburn
	else if (ereg('Mozilla/([0-9].[0-9]{1,2})', $user_agent, $log_version) && ereg('Safari/([0-9]*)', $user_agent, $log_version2))
185 4473 psotfx
	{
186 4612 acydburn
		$browser_version = $log_version[1] . '.' . $log_version2[1];
187 4612 acydburn
		$browser_agent = 'safari';
188 5114 acydburn
	}
189 4612 acydburn
	else if (ereg('Mozilla/([0-9].[0-9]{1,2})', $user_agent, $log_version))
190 4612 acydburn
	{
191 4473 psotfx
		$browser_version = $log_version[1];
192 4473 psotfx
		$browser_agent = 'mozilla';
193 5114 acydburn
	}
194 4612 acydburn
	else
195 4473 psotfx
	{
196 4473 psotfx
		$browser_version = 0;
197 4473 psotfx
		$browser_agent = 'other';
198 5114 acydburn
	}
199 4473 psotfx
200 4473 psotfx
	// Correct the mime type - we force application/octetstream for all files, except images
201 4473 psotfx
	// Please do not change this, it is a security precaution
202 4984 acydburn
	if ($category == ATTACHMENT_CATEGORY_NONE && strpos($attachment['mimetype'], 'image') === false)
203 4473 psotfx
	{
204 4473 psotfx
		$attachment['mimetype'] = ($browser_agent == 'ie' || $browser_agent == 'opera') ? 'application/octetstream' : 'application/octet-stream';
205 4473 psotfx
	}
206 4473 psotfx
207 5138 acydburn
	if (@ob_get_length())
208 5032 acydburn
	{
209 5032 acydburn
		@ob_end_clean();
210 5032 acydburn
	}
211 5032 acydburn
212 4473 psotfx
	// Now the tricky part... let's dance
213 4473 psotfx
	header('Pragma: public');
214 4473 psotfx
215 4473 psotfx
	// Send out the Headers
216 4473 psotfx
	header('Content-Type: ' . $attachment['mimetype'] . '; name="' . $attachment['real_filename'] . '"');
217 4473 psotfx
	header('Content-Disposition: inline; filename="' . $attachment['real_filename'] . '"');
218 4473 psotfx
219 4473 psotfx
	// Now send the File Contents to the Browser
220 4473 psotfx
	$size = @filesize($filename);
221 4473 psotfx
	if ($size)
222 4473 psotfx
	{
223 4473 psotfx
		header("Content-length: $size");
224 4473 psotfx
	}
225 4612 acydburn
	$result = @readfile($filename);
226 4986 acydburn
227 4612 acydburn
	if (!$result)
228 4612 acydburn
	{
229 4612 acydburn
		trigger_error('Unable to deliver file.<br />Error was: ' . $php_errormsg, E_USER_WARNING);
230 4612 acydburn
	}
231 4612 acydburn
232 4612 acydburn
	flush();
233 4473 psotfx
	exit;
234 4473 psotfx
}
235 4682 acydburn
236 5114 acydburn
/**
237 5114 acydburn
* Check if downloading item is allowed
238 5114 acydburn
*/
239 4682 acydburn
function download_allowed()
240 4682 acydburn
{
241 4682 acydburn
	global $config, $user, $db;
242 4682 acydburn
243 4682 acydburn
	if (!$config['secure_downloads'])
244 4682 acydburn
	{
245 4682 acydburn
		return true;
246 4682 acydburn
	}
247 4682 acydburn
248 4844 acydburn
	$url = (getenv('HTTP_REFERER')) ? trim(getenv('HTTP_REFERER')) : trim($_SERVER['HTTP_REFERER']);
249 4682 acydburn
250 4844 acydburn
	if (!$url)
251 4682 acydburn
	{
252 4682 acydburn
		return ($config['secure_allow_empty_referer']) ? true : false;
253 4682 acydburn
	}
254 4682 acydburn
255 4682 acydburn
	// Split URL into domain and script part
256 4682 acydburn
	$url = explode('?', str_replace(array('http://', 'https://'), array('', ''), $url));
257 4682 acydburn
	$hostname = trim($url[0]);
258 4682 acydburn
	unset($url);
259 4682 acydburn
260 4844 acydburn
	$allowed = ($config['secure_allow_deny']) ? false : true;
261 4682 acydburn
	$iplist = array();
262 4682 acydburn
263 4682 acydburn
	$ip_ary = gethostbynamel($hostname);
264 4682 acydburn
265 4682 acydburn
	foreach ($ip_ary as $ip)
266 4682 acydburn
	{
267 4844 acydburn
		if ($ip)
268 4682 acydburn
		{
269 4682 acydburn
			$iplist[] = $ip;
270 4682 acydburn
		}
271 4682 acydburn
	}
272 4682 acydburn
273 4682 acydburn
	// Check for own server...
274 4682 acydburn
	if (preg_match('#^.*?' . $config['server_name'] . '.*?$#i', $hostname))
275 4682 acydburn
	{
276 4682 acydburn
		$allowed = true;
277 4682 acydburn
	}
278 4682 acydburn
279 4682 acydburn
	// Get IP's and Hostnames
280 4682 acydburn
	if (!$allowed)
281 4682 acydburn
	{
282 4682 acydburn
		$sql = 'SELECT site_ip, site_hostname, ip_exclude
283 4682 acydburn
			FROM ' . SITELIST_TABLE;
284 4682 acydburn
		$result = $db->sql_query($sql);
285 4682 acydburn
286 4682 acydburn
		while ($row = $db->sql_fetchrow($result))
287 4682 acydburn
		{
288 4844 acydburn
			$site_ip = trim($row['site_ip']);
289 4844 acydburn
			$site_hostname = trim($row['site_hostname']);
290 4844 acydburn
291 4844 acydburn
			if ($site_ip)
292 4682 acydburn
			{
293 4682 acydburn
				foreach ($iplist as $ip)
294 4682 acydburn
				{
295 4844 acydburn
					if (preg_match('#^' . str_replace('*', '.*?', $site_ip) . '$#i', $ip))
296 4682 acydburn
					{
297 4844 acydburn
						if ($row['ip_exclude'])
298 4682 acydburn
						{
299 4682 acydburn
							$allowed = ($config['secure_allow_deny']) ? false : true;
300 4682 acydburn
							break 2;
301 4682 acydburn
						}
302 4682 acydburn
						else
303 4682 acydburn
						{
304 4682 acydburn
							$allowed = ($config['secure_allow_deny']) ? true : false;
305 4682 acydburn
						}
306 4682 acydburn
					}
307 4682 acydburn
				}
308 4682 acydburn
			}
309 4682 acydburn
310 4844 acydburn
			if ($site_hostname)
311 4682 acydburn
			{
312 4844 acydburn
				if (preg_match('#^' . str_replace('*', '.*?', $site_hostname) . '$#i', $hostname))
313 4682 acydburn
				{
314 4844 acydburn
					if ($row['ip_exclude'])
315 4682 acydburn
					{
316 4682 acydburn
						$allowed = ($config['secure_allow_deny']) ? false : true;
317 4682 acydburn
						break;
318 4682 acydburn
					}
319 4682 acydburn
					else
320 4682 acydburn
					{
321 4682 acydburn
						$allowed = ($config['secure_allow_deny']) ? true : false;
322 4682 acydburn
					}
323 4682 acydburn
				}
324 4682 acydburn
			}
325 4682 acydburn
		}
326 4844 acydburn
327 4682 acydburn
		$db->sql_freeresult($result);
328 4682 acydburn
	}
329 4682 acydburn
330 4682 acydburn
	return $allowed;
331 4682 acydburn
}
332 4682 acydburn
333 3807 acydburn
?>