root / tags / milestone_3 / phpBB / download.php

View | Annotate | Download (8 KB)

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
?>