Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

file.php

Zuletzt modifiziert: 09.10.2024, 12:50 - Dateigröße: 15.87 KiB


001  <?php
002  /**
003  *
004  * @package phpBB3
005  * @version $Id$
006  * @copyright (c) 2005 phpBB Group
007  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
008  *
009  */
010   
011  /**
012  * @ignore
013  */
014  define('IN_PHPBB', true);
015  $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../';
016  $phpEx = substr(strrchr(__FILE__, '.'), 1);
017   
018  if (isset($_GET['avatar']))
019  {
020      require($phpbb_root_path . 'config.' . $phpEx);
021      require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx);
022      require($phpbb_root_path . 'includes/cache.' . $phpEx);
023      require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
024      require($phpbb_root_path . 'includes/constants.' . $phpEx);
025   
026      $db = new $sql_db();
027      $cache = new cache();
028   
029      // Connect to DB
030      if (!@$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false))
031      {
032          exit;
033      }
034      unset($dbpasswd);
035      
036      // worst-case default
037      $browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : 'msie 6.0';
038   
039      $config = $cache->obtain_config();
040      $filename = $_GET['avatar'];
041      $avatar_group = false;
042      if ($filename[0] === 'g')
043      {
044          $avatar_group = true;
045          $filename = substr($filename, 1);
046      }
047      
048      // '==' is not a bug - . as the first char is as bad as no dot at all
049      if (strpos($filename, '.') == false)
050      {
051          header('HTTP/1.0 403 forbidden');
052          if (!empty($cache))
053          {
054              $cache->unload();
055          }
056          $db->sql_close();
057          exit;
058      }
059      
060      $ext        = substr(strrchr($filename, '.'), 1);
061      $stamp        = (int) substr(stristr($filename, '_'), 1);
062      $filename    = (int) $filename;
063      
064      // let's see if we have to send the file at all
065      $last_load     =  isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime(trim($_SERVER['HTTP_IF_MODIFIED_SINCE'])) : false;
066      if (strpos(strtolower($browser), 'msie 6.0') === false)
067      {
068          if ($last_load !== false && $last_load <= $stamp)
069          {
070              header('Not Modified', true, 304);
071              // seems that we need those too ... browsers
072              header('Pragma: public');
073              header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000));
074              exit();
075          } 
076          else
077          {
078              header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stamp) . ' GMT');
079          }
080      }
081      
082      if (!in_array($ext, array('png', 'gif', 'jpg', 'jpeg')))
083      {
084          // no way such an avatar could exist. They are not following the rules, stop the show.
085          header("HTTP/1.0 403 forbidden");
086          if (!empty($cache))
087          {
088              $cache->unload();
089          }
090          $db->sql_close();
091          exit;
092      }
093      
094      if (!$filename)
095      {
096          // no way such an avatar could exist. They are not following the rules, stop the show.
097          header("HTTP/1.0 403 forbidden");
098          if (!empty($cache))
099          {
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  ?>