Ejemplo n.º 1
0
 /**
  * Test Settings
  */
 function test_upload(&$error, $upload_dir, $create_directory = false)
 {
     global $user, $phpbb_root_path;
     // Does the target directory exist, is it a directory and writable.
     if ($create_directory) {
         if (!file_exists($phpbb_root_path . $upload_dir)) {
             @mkdir($phpbb_root_path . $upload_dir, 0777);
             try {
                 $this->filesystem->phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE);
             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                 // Do nothing
             }
         }
     }
     if (!file_exists($phpbb_root_path . $upload_dir)) {
         $error[] = sprintf($user->lang['NO_UPLOAD_DIR'], $upload_dir);
         return;
     }
     if (!is_dir($phpbb_root_path . $upload_dir)) {
         $error[] = sprintf($user->lang['UPLOAD_NOT_DIR'], $upload_dir);
         return;
     }
     if (!$this->filesystem->is_writable($phpbb_root_path . $upload_dir)) {
         $error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir);
         return;
     }
 }
Ejemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 public function run()
 {
     $config_written = true;
     // Create config.php
     $path_to_config = $this->phpbb_root_path . 'config.' . $this->php_ext;
     $fp = @fopen($path_to_config, 'w');
     if (!$fp) {
         $config_written = false;
     }
     $config_content = $this->get_config_data();
     if (!@fwrite($fp, $config_content)) {
         $config_written = false;
     }
     @fclose($fp);
     // chmod config.php to be only readable
     if ($config_written) {
         try {
             $this->filesystem->phpbb_chmod($path_to_config, \phpbb\filesystem\filesystem_interface::CHMOD_READ);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing, the user will get a notice later
         }
     } else {
         $this->iohandler->add_error_message('UNABLE_TO_WRITE_CONFIG_FILE');
         $this->iohandler->send_response();
         throw new user_interaction_required_exception();
     }
     // Create a lock file to indicate that there is an install in progress
     $fp = @fopen($this->phpbb_root_path . 'cache/install_lock', 'wb');
     if ($fp === false) {
         // We were unable to create the lock file - abort
         $this->iohandler->add_error_message('UNABLE_TO_WRITE_LOCK');
         $this->iohandler->send_response();
         throw new user_interaction_required_exception();
     }
     @fclose($fp);
     try {
         $this->filesystem->phpbb_chmod($this->phpbb_root_path . 'cache/install_lock', 0777);
     } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
         // Do nothing, the user will get a notice later
     }
 }
Ejemplo n.º 3
0
 /**
  * Write cache data to a specified file
  *
  * 'data_global' is a special case and the generated format is different for this file:
  * <code>
  * <?php exit; ?>
  * (expiration)
  * (length of var and serialised data)
  * (var)
  * (serialised data)
  * ... (repeat)
  * </code>
  *
  * The other files have a similar format:
  * <code>
  * <?php exit; ?>
  * (expiration)
  * (query) [SQL files only]
  * (length of serialised data)
  * (serialised data)
  * </code>
  *
  * @access private
  * @param string $filename Filename to write
  * @param mixed $data Data to store
  * @param int $expires Timestamp when the data expires
  * @param string $query Query when caching SQL queries
  * @return bool True if the file was successfully created, otherwise false
  */
 function _write($filename, $data = null, $expires = 0, $query = '')
 {
     global $phpEx;
     $filename = $this->clean_varname($filename);
     $file = "{$this->cache_dir}{$filename}.{$phpEx}";
     $lock = new \phpbb\lock\flock($file);
     $lock->acquire();
     if ($handle = @fopen($file, 'wb')) {
         // File header
         fwrite($handle, '<' . '?php exit; ?' . '>');
         if ($filename == 'data_global') {
             // Global data is a different format
             foreach ($this->vars as $var => $data) {
                 if (strpos($var, "\r") !== false || strpos($var, "\n") !== false) {
                     // CR/LF would cause fgets() to read the cache file incorrectly
                     // do not cache test entries, they probably won't be read back
                     // the cache keys should really be alphanumeric with a few symbols.
                     continue;
                 }
                 $data = serialize($data);
                 // Write out the expiration time
                 fwrite($handle, "\n" . $this->var_expires[$var] . "\n");
                 // Length of the remaining data for this var (ignoring two LF's)
                 fwrite($handle, strlen($data . $var) . "\n");
                 fwrite($handle, $var . "\n");
                 fwrite($handle, $data);
             }
         } else {
             fwrite($handle, "\n" . $expires . "\n");
             if (strpos($filename, 'sql_') === 0) {
                 fwrite($handle, $query . "\n");
             }
             $data = serialize($data);
             fwrite($handle, strlen($data) . "\n");
             fwrite($handle, $data);
         }
         fclose($handle);
         if (function_exists('opcache_invalidate')) {
             @opcache_invalidate($this->cache_file);
         }
         try {
             $this->filesystem->phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
         $return_value = true;
     } else {
         $return_value = false;
     }
     $lock->release();
     return $return_value;
 }
Ejemplo n.º 4
0
 /**
  * Check if a directory is readable and writable
  *
  * @param string	$dir		Filename
  * @param bool		$failable	Whether failing test should abort the installation process
  */
 protected function check_dir($dir, $failable = false)
 {
     $path = $this->phpbb_root_path . $dir;
     $exists = $writable = false;
     // Try to create the directory if it does not exist
     if (!file_exists($path)) {
         try {
             $this->filesystem->mkdir($path, 0777);
             $this->filesystem->phpbb_chmod($path, \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE);
             $exists = true;
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
     }
     // Now really check
     if (file_exists($path) && is_dir($path)) {
         try {
             $exists = true;
             $this->filesystem->phpbb_chmod($path, \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
     }
     if ($this->filesystem->is_writable($path)) {
         $writable = true;
     }
     $this->set_test_passed($exists && $writable || $failable);
     if (!($exists && $writable)) {
         $title = $exists ? 'DIRECTORY_NOT_WRITABLE' : 'DIRECTORY_NOT_EXISTS';
         $lang_suffix = '_EXPLAIN';
         $lang_suffix .= $failable ? '_OPTIONAL' : '';
         $description = array($title . $lang_suffix, $dir);
         if ($failable) {
             $this->response->add_warning_message($title, $description);
         } else {
             $this->response->add_error_message($title, $description);
         }
     }
 }
Ejemplo n.º 5
0
 /**
  * Save queue
  */
 function save()
 {
     if (!sizeof($this->data)) {
         return;
     }
     $lock = new \phpbb\lock\flock($this->cache_file);
     $lock->acquire();
     if (file_exists($this->cache_file)) {
         include $this->cache_file;
         foreach ($this->queue_data as $object => $data_ary) {
             if (isset($this->data[$object]) && sizeof($this->data[$object])) {
                 $this->data[$object]['data'] = array_merge($data_ary['data'], $this->data[$object]['data']);
             } else {
                 $this->data[$object]['data'] = $data_ary['data'];
             }
         }
     }
     if ($fp = @fopen($this->cache_file, 'w')) {
         fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>");
         fclose($fp);
         try {
             $this->filesystem->phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
         $this->data = array();
     }
     $lock->release();
 }
Ejemplo n.º 6
0
 /**
  * Extract archive
  */
 function extract($dst)
 {
     $fzread = $this->isbz && function_exists('bzread') ? 'bzread' : ($this->isgz && @extension_loaded('zlib') ? 'gzread' : 'fread');
     // Run through the file and grab directory entries
     while ($buffer = $fzread($this->fp, 512)) {
         $tmp = unpack('A6magic', substr($buffer, 257, 6));
         if (trim($tmp['magic']) == 'ustar') {
             $tmp = unpack('A100name', $buffer);
             $filename = trim($tmp['name']);
             $tmp = unpack('Atype', substr($buffer, 156, 1));
             $filetype = (int) trim($tmp['type']);
             $tmp = unpack('A12size', substr($buffer, 124, 12));
             $filesize = octdec((int) trim($tmp['size']));
             $target_filename = "{$dst}{$filename}";
             if ($filetype == 5) {
                 if (!is_dir($target_filename)) {
                     $str = '';
                     $folders = explode('/', $target_filename);
                     // Create and folders and subfolders if they do not exist
                     foreach ($folders as $folder) {
                         $folder = trim($folder);
                         if (!$folder) {
                             continue;
                         }
                         $str = !empty($str) ? $str . '/' . $folder : $folder;
                         if (!is_dir($str)) {
                             if (!@mkdir($str, 0777)) {
                                 trigger_error("Could not create directory {$folder}");
                             }
                             try {
                                 $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
                             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                                 // Do nothing
                             }
                         }
                     }
                 }
             } else {
                 if ($filesize >= 0 && ($filetype == 0 || $filetype == "")) {
                     // Some archivers are punks, they don't properly order the folders in their archives!
                     $str = '';
                     $folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME));
                     // Create and folders and subfolders if they do not exist
                     foreach ($folders as $folder) {
                         $folder = trim($folder);
                         if (!$folder) {
                             continue;
                         }
                         $str = !empty($str) ? $str . '/' . $folder : $folder;
                         if (!is_dir($str)) {
                             if (!@mkdir($str, 0777)) {
                                 trigger_error("Could not create directory {$folder}");
                             }
                             try {
                                 $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
                             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                                 // Do nothing
                             }
                         }
                     }
                     // Write out the files
                     if (!($fp = fopen($target_filename, 'wb'))) {
                         trigger_error("Couldn't create file {$filename}");
                     }
                     try {
                         $this->filesystem->phpbb_chmod($target_filename, CHMOD_READ);
                     } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                         // Do nothing
                     }
                     // Grab the file contents
                     fwrite($fp, $filesize ? $fzread($this->fp, $filesize + 511 & ~511) : '', $filesize);
                     fclose($fp);
                 }
             }
         }
     }
 }
Ejemplo n.º 7
0
 /**
  * Writes the config file to disk, or if unable to do so offers alternative methods
  */
 function create_config_file($mode, $sub)
 {
     global $lang, $template, $phpbb_root_path, $phpEx;
     $this->page_title = $lang['STAGE_CONFIG_FILE'];
     // Obtain any submitted data
     $data = $this->get_submitted_data();
     if ($data['dbms'] == '') {
         // Someone's been silly and tried calling this page direct
         // So we send them back to the start to do it again properly
         $this->p_master->redirect("index.{$phpEx}?mode=install");
     }
     $s_hidden_fields = $data['img_imagick'] ? '<input type="hidden" name="img_imagick" value="' . addslashes($data['img_imagick']) . '" />' : '';
     $s_hidden_fields .= '<input type="hidden" name="language" value="' . $data['language'] . '" />';
     $written = false;
     // Create a list of any PHP modules we wish to have loaded
     $available_dbms = get_available_dbms($data['dbms']);
     // Create a lock file to indicate that there is an install in progress
     $fp = @fopen($phpbb_root_path . 'cache/install_lock', 'wb');
     if ($fp === false) {
         // We were unable to create the lock file - abort
         $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__);
     }
     @fclose($fp);
     @chmod($phpbb_root_path . 'cache/install_lock', 0777);
     // Time to convert the data provided into a config file
     $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER']);
     // Attempt to write out the config file directly. If it works, this is the easiest way to do it ...
     if (file_exists($phpbb_root_path . 'config.' . $phpEx) && $this->filesystem->is_writable($phpbb_root_path . 'config.' . $phpEx) || $this->filesystem->is_writable($phpbb_root_path)) {
         // Assume it will work ... if nothing goes wrong below
         $written = true;
         if (!($fp = @fopen($phpbb_root_path . 'config.' . $phpEx, 'w'))) {
             // Something went wrong ... so let's try another method
             $written = false;
         }
         if (!@fwrite($fp, $config_data)) {
             // Something went wrong ... so let's try another method
             $written = false;
         }
         @fclose($fp);
         if ($written) {
             // We may revert back to chmod() if we see problems with users not able to change their config.php file directly
             try {
                 $this->filesystem->phpbb_chmod($phpbb_root_path . 'config.' . $phpEx, CHMOD_READ);
             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                 // Do nothing
             }
         }
     }
     if (isset($_POST['dldone'])) {
         // Do a basic check to make sure that the file has been uploaded
         // Note that all we check is that the file has _something_ in it
         // We don't compare the contents exactly - if they can't upload
         // a single file correctly, it's likely they will have other problems....
         if (filesize($phpbb_root_path . 'config.' . $phpEx) > 10) {
             $written = true;
         }
     }
     $config_options = array_merge($this->db_config_options, $this->admin_config_options);
     foreach ($config_options as $config_key => $vars) {
         if (!is_array($vars)) {
             continue;
         }
         $s_hidden_fields .= '<input type="hidden" name="' . $config_key . '" value="' . $data[$config_key] . '" />';
     }
     if (!$written) {
         // OK, so it didn't work let's try the alternatives
         if (isset($_POST['dlconfig'])) {
             // They want a copy of the file to download, so send the relevant headers and dump out the data
             header("Content-Type: text/x-delimtext; name=\"config.{$phpEx}\"");
             header("Content-disposition: attachment; filename=config.{$phpEx}");
             echo $config_data;
             exit;
         }
         // The option to download the config file is always available, so output it here
         $template->assign_vars(array('BODY' => $lang['CONFIG_FILE_UNABLE_WRITE'], 'L_DL_CONFIG' => $lang['DL_CONFIG'], 'L_DL_CONFIG_EXPLAIN' => $lang['DL_CONFIG_EXPLAIN'], 'L_DL_DONE' => $lang['DONE'], 'L_DL_DOWNLOAD' => $lang['DL_DOWNLOAD'], 'S_HIDDEN' => $s_hidden_fields, 'S_SHOW_DOWNLOAD' => true, 'U_ACTION' => $this->p_master->module_url . "?mode={$mode}&amp;sub=config_file"));
         return;
     } else {
         $template->assign_vars(array('BODY' => $lang['CONFIG_FILE_WRITTEN'], 'L_SUBMIT' => $lang['NEXT_STEP'], 'S_HIDDEN' => $s_hidden_fields, 'U_ACTION' => $this->p_master->module_url . "?mode={$mode}&amp;sub=advanced"));
         return;
     }
 }
Ejemplo n.º 8
0
 /**
  * Move file to destination folder
  * The phpbb_root_path variable will be applied to the destination path
  *
  * @param string $destination Destination path, for example $config['avatar_path']
  * @param bool $overwrite If set to true, an already existing file will be overwritten
  * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped
  * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()}
  *
  * @access public
  */
 function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false)
 {
     global $user, $phpbb_root_path;
     if (sizeof($this->error)) {
         return false;
     }
     $chmod = $chmod === false ? CHMOD_READ | CHMOD_WRITE : $chmod;
     // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it...
     $this->destination_path = $phpbb_root_path . $destination;
     // Check if the destination path exist...
     if (!file_exists($this->destination_path)) {
         @unlink($this->filename);
         return false;
     }
     $upload_mode = @ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on' ? 'move' : 'copy';
     $upload_mode = $this->local ? 'local' : $upload_mode;
     $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname);
     // Check if the file already exist, else there is something wrong...
     if (file_exists($this->destination_file) && !$overwrite) {
         @unlink($this->filename);
         $this->error[] = $user->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file);
         $this->file_moved = false;
         return false;
     } else {
         if (file_exists($this->destination_file)) {
             @unlink($this->destination_file);
         }
         switch ($upload_mode) {
             case 'copy':
                 if (!@copy($this->filename, $this->destination_file)) {
                     if (!@move_uploaded_file($this->filename, $this->destination_file)) {
                         $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
                     }
                 }
                 break;
             case 'move':
                 if (!@move_uploaded_file($this->filename, $this->destination_file)) {
                     if (!@copy($this->filename, $this->destination_file)) {
                         $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
                     }
                 }
                 break;
             case 'local':
                 if (!@copy($this->filename, $this->destination_file)) {
                     $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
                 }
                 break;
         }
         // Remove temporary filename
         @unlink($this->filename);
         if (sizeof($this->error)) {
             return false;
         }
         try {
             $this->filesystem->phpbb_chmod($this->destination_file, $chmod);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
     }
     // Try to get real filesize from destination folder
     $this->filesize = @filesize($this->destination_file) ? @filesize($this->destination_file) : $this->filesize;
     // Get mimetype of supplied file
     $this->mimetype = $this->get_mimetype($this->destination_file);
     if ($this->is_image() && !$skip_image_check) {
         $this->width = $this->height = 0;
         // Get imagesize class
         $imagesize = new \fastImageSize\fastImageSize();
         $this->image_info = $imagesize->getImageSize($this->destination_file, $this->mimetype);
         if ($this->image_info !== false) {
             $this->width = $this->image_info['width'];
             $this->height = $this->image_info['height'];
             // Check image type
             $types = fileupload::image_types();
             if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']])) {
                 if (!isset($types[$this->image_info['type']])) {
                     $this->error[] = $user->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype);
                 } else {
                     $this->error[] = $user->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension);
                 }
             }
             // Make sure the dimensions match a valid image
             if (empty($this->width) || empty($this->height)) {
                 $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE'];
             }
         } else {
             $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
         }
     }
     $this->file_moved = true;
     $this->additional_checks();
     unset($this->upload);
     return true;
 }