Merge branch 'ent-7911-errores-file-manager' into 'develop'

Fixed issues with files upload

Closes pandora_enterprise#7911

See merge request artica/pandorafms!4370
This commit is contained in:
Daniel Rodriguez 2021-09-01 13:18:10 +00:00
commit b8e1391ffd
3 changed files with 128 additions and 120 deletions

View File

@ -47,16 +47,17 @@ if (isset($config['filemanager']['message']) === true) {
$config['filemanager']['message'] = null;
}
$directory = (string) get_parameter('directory');
if (empty($directory) === true) {
$directory = 'images';
} else {
$directory = str_replace('\\', '/', $directory);
$directory = filemanager_safe_directory($directory, 'images');
}
// Add custom directories here.
$fallback_directory = 'images';
// Get directory.
$directory = (string) get_parameter('directory');
if (empty($directory) === true) {
$directory = $fallback_directory;
} else {
$directory = str_replace('\\', '/', $directory);
$directory = filemanager_safe_directory($directory, $fallback_directory);
}
// Banned directories.
$banned_directories['include'] = true;
$banned_directories['godmode'] = true;
@ -76,7 +77,7 @@ echo '<h4>'.__('Index of %s', $directory).'</h4>';
$upload_file_or_zip = (bool) get_parameter('upload_file_or_zip');
$create_text_file = (bool) get_parameter('create_text_file');
$default_real_directory = realpath($config['homedir'].'/'.$fallback_directory);
$default_real_directory = realpath($config['homedir'].'/');
if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory);

View File

@ -26,7 +26,6 @@
* ============================================================================
*/
// Get global data.
// Constants.
define('MIME_UNKNOWN', 0);
@ -165,21 +164,19 @@ function upload_file($upload_file_or_zip, $default_real_directory)
if ($upload_file === true) {
if (isset($_FILES['file']) === true && empty($_FILES['file']['name']) === false) {
$filename = $_FILES['file']['name'];
$filesize = $_FILES['file']['size'];
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory'));
$directory = filemanager_safe_directory((string) get_parameter('directory'));
$umask = io_safe_output((string) get_parameter('umask'));
if (strpos($real_directory, $default_real_directory) !== 0) {
// Perform security check to determine whether received upload directory is part of the default path for caller uploader and user is not trying to access an external path (avoid execution of PHP files in directories that are not explicitly controlled by corresponding .htaccess).
// Perform security check to determine whether received upload
// directory is part of the default path for caller uploader and
// user is not trying to access an external path (avoid
// execution of PHP files in directories that are not explicitly
// controlled by corresponding .htaccess).
ui_print_error_message(__('Security error'));
} else {
// Copy file to directory and change name.
if (empty($directory) === true) {
$nombre_archivo = $real_directory.'/'.$filename;
} else {
$nombre_archivo = $default_real_directory.'/'.$directory.'/'.$filename;
}
if (! @copy($_FILES['file']['tmp_name'], $nombre_archivo)) {
$config['filemanager']['message'] = ui_print_error_message(__('Upload error'));
@ -204,10 +201,8 @@ function upload_file($upload_file_or_zip, $default_real_directory)
&& empty($_FILES['file']['name']) === false
) {
$filename = $_FILES['file']['name'];
$filesize = $_FILES['file']['size'];
$filepath = $_FILES['file']['tmp_name'];
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory'));
$directory = filemanager_safe_directory((string) get_parameter('directory'));
if (strpos($real_directory, $default_real_directory) !== 0) {
// Perform security check to determine whether received upload
@ -259,33 +254,38 @@ function create_text_file($default_real_directory)
if (empty($filename) === false) {
$real_directory = filemanager_safe_directory((string) get_parameter('real_directory'));
$directory = filemanager_safe_directory((string) get_parameter('directory'));
$umask = (string) get_parameter('umask');
if (strpos($real_directory, $default_real_directory) !== 0) {
// Perform security check to determine whether received upload directory is part of the default path for caller uploader and user is not trying to access an external path (avoid execution of PHP files in directories that are not explicitly controlled by corresponding .htaccess).
// Perform security check to determine whether received upload
// directory is part of the default path for caller uploader and
// user is not trying to access an external path (avoid execution
// of PHP files in directories that are not explicitly controlled by
// corresponding .htaccess).
ui_print_error_message(__('Security error'));
} else {
if (empty($directory) === true) {
$nombre_archivo = $real_directory.'/'.$filename;
} else {
$nombre_archivo = $default_real_directory.'/'.$directory.'/'.$filename;
}
if (! @touch($nombre_archivo)) {
$config['filemanager']['message'] = ui_print_error_message(__('Error creating file'));
} else {
try {
// Create the file.
$result = touch($nombre_archivo);
if ($result === true) {
if ($umask !== '') {
chmod($nombre_archivo, $umask);
}
ui_print_success_message(__('Upload correct'));
ui_print_success_message(__('File created correctly'));
$config['filemanager']['correct_upload_file'] = 1;
} else {
throw new Exception(__('Error creating file'));
}
} catch (Exception $ex) {
$config['filemanager']['message'] = ui_print_error_message($ex->getMessage());
}
}
} else {
ui_print_error_message(__('Error creating file with empty name'));
$config['filemanager']['message'] = ui_print_error_message(__('Error creating file with empty name'));
}
}
@ -295,13 +295,18 @@ $create_dir = (bool) get_parameter('create_dir');
if ($create_dir === true) {
global $config;
$sec2 = get_parameter('sec2');
if ($sec2 === 'enterprise/godmode/agentes/collections' || $sec2 === 'advanced/collections') {
$homedir_filemanager = io_safe_output($config['attachment_store']).'/collection';
} else {
$homedir_filemanager = io_safe_output($config['homedir']);
}
$config['filemanager'] = [];
$config['filemanager']['correct_create_dir'] = 0;
$config['filemanager']['message'] = null;
$directory = filemanager_safe_directory((string) get_parameter('directory', '/'));
$directory = filemanager_safe_directory((string) get_parameter('directory'));
$hash = (string) get_parameter('hash');
$testHash = md5($directory.$config['server_unique_identifier']);
@ -312,12 +317,23 @@ if ($create_dir === true) {
if (empty($dirname) === false) {
// Create directory.
@mkdir(
$homedir_filemanager.'/'.$directory.'/'.$dirname
);
$config['filemanager']['message'] = ui_print_success_message(__('Directory created'), '', true);
try {
// If directory exists, add an slash at end.
if (empty($directory) === false) {
$directory .= '/';
}
$result = mkdir($homedir_filemanager.'/'.$directory.$dirname);
if ($result === true) {
$config['filemanager']['message'] = ui_print_success_message(__('Directory created'), '', true);
$config['filemanager']['correct_create_dir'] = 1;
} else {
throw new Exception(__('Something gone wrong creating directory'));
}
} catch (Exception $ex) {
$config['filemanager']['message'] = ui_print_error_message($ex->getMessage(), '', true);
}
} else {
$config['filemanager']['message'] = ui_print_error_message(__('Error creating file with empty name'), '', true);
}
@ -367,7 +383,9 @@ if ($delete_file === true) {
/**
* Recursive delete directory and empty or not directory.
*
* @param string $dir The dir to deletete
* @param string $dir The dir to deletete.
*
* @return void
*/
function filemanager_delete_directory($dir)
{
@ -397,8 +415,9 @@ function filemanager_delete_directory($dir)
* Read a directory recursibly and return a array with the files with
* the absolute path and relative
*
* @param string $dir absoute dir to scan
* @param string $relative_path Relative path to scan, by default ''
* @param string $dir Absoute dir to scan.
* @param string $relative_path Relative path to scan, by default ''.
* @param boolean $add_empty_dirs Add empty dirs.
*
* @return array The files in the dirs, empty array for empty dir of files.
*/
@ -406,14 +425,14 @@ function filemanager_read_recursive_dir($dir, $relative_path='', $add_empty_dirs
{
$return = [];
// Windows compatibility
// Windows compatibility.
$dir = str_replace('\\', '/', $dir);
$relative_path = str_replace('\\', '/', $relative_path);
if ($handle = opendir($dir)) {
while (false !== ($entry = readdir($handle))) {
if (($entry != '.') && ($entry != '..')) {
if (is_dir($dir.$entry)) {
if (($entry !== '.') && ($entry !== '..')) {
if (is_dir($dir.$entry) === true) {
$return[] = [
'relative' => $relative_path.$entry,
'absolute' => $dir.$entry,
@ -454,9 +473,13 @@ function filemanager_read_recursive_dir($dir, $relative_path='', $add_empty_dirs
* @param string $url The url to set in the forms and some links in the explorer.
* @param string $father The directory father don't navigate bottom this.
* @param boolean $editor The flag to set the edition of text files.
* @param boolean $readOnly The flag to set read only.
* @param string $url_file The url to put in the files instead the default. By default empty string and use the url of filemanager.
* @param boolean $download_button The flag to show download button, by default false.
* @param string $umask The umask as hex values to set the new files or updload.
* @param mixed $homedir_filemanager Homedir of file manager.
*
* @return void
*/
function filemanager_file_explorer(
$real_directory,
@ -472,7 +495,7 @@ function filemanager_file_explorer(
) {
global $config;
// Windows compatibility
// Windows compatibility.
$real_directory = str_replace('\\', '/', $real_directory);
$relative_directory = str_replace('\\', '/', $relative_directory);
$father = str_replace('\\', '/', $father);
@ -482,7 +505,7 @@ function filemanager_file_explorer(
}
$hack_metaconsole = '';
if (defined('METACONSOLE')) {
if (is_metaconsole() === true) {
$hack_metaconsole = '../../';
}
@ -567,28 +590,21 @@ function filemanager_file_explorer(
}
</script>
<?php
// List files
if (! is_dir($real_directory)) {
// List files.
if (is_dir($real_directory) === false) {
echo __('Directory %s doesn\'t exist!', $relative_directory);
return;
}
$files = filemanager_list_dir($real_directory);
if (!empty($files)) {
if (empty($files) === false) {
$table = new stdClass();
$table->width = '100%';
$table->id = 'table_filemanager';
if (!defined('METACONSOLE')) {
$table->class = 'info_table';
$table->title = '<span>'.__('Index of %s', $relative_directory).'</span>';
}
if (defined('METACONSOLE')) {
$table->class = 'databox_tactical';
$table->class = (is_metaconsole() === true) ? 'databox_tactical' : 'info_table';
$table->title = '<span>'.__('Index of %s', $relative_directory).'</span>';
}
$table->colspan = [];
$table->data = [];
$table->head = [];
@ -609,9 +625,10 @@ function filemanager_file_explorer(
$prev_dir = explode('/', $relative_directory);
$prev_dir_str = '';
for ($i = 0; $i < (count($prev_dir) - 1); $i++) {
$prev_dir_count = count($prev_dir);
for ($i = 0; $i < ($prev_dir_count - 1); $i++) {
$prev_dir_str .= $prev_dir[$i];
if ($i < (count($prev_dir) - 2)) {
if ($i < ($prev_dir_count - 2)) {
$prev_dir_str .= '/';
}
}
@ -649,16 +666,16 @@ function filemanager_file_explorer(
break;
case MIME_UNKNOWN:
if ($fileinfo['size'] == 0) {
if ((int) $fileinfo['size'] === 0) {
if ((strstr($fileinfo['name'], '.txt') !== false) || (strstr($fileinfo['name'], '.conf') !== false) || (strstr($fileinfo['name'], '.sql') !== false) || (strstr($fileinfo['name'], '.pl') !== false)) {
$fileinfo['mime'] = MIME_TEXT;
$data[0] = html_print_image('images/mimetypes/text.png', true, ['title' => __('Text file'), 'class' => 'invert_filter']);
} else {
// unknow
// Unknown.
$data[0] = '';
}
} else {
// pdf
// Pdf.
$data[0] = '';
}
break;
@ -670,8 +687,8 @@ function filemanager_file_explorer(
if ($fileinfo['is_dir']) {
$data[1] = '<a href="'.$url.'&directory='.$relative_directory.'/'.$fileinfo['name'].'&hash2='.md5($relative_directory.'/'.$fileinfo['name'].$config['server_unique_identifier']).'">'.$fileinfo['name'].'</a>';
} else if (!empty($url_file)) {
// Set the custom url file
} else if (empty($url_file) === false) {
// Set the custom url file.
$url_file_clean = str_replace('[FILE_FULLPATH]', $fileinfo['realpath'], $url_file);
$data[1] = '<a href="'.$url_file_clean.'">'.$fileinfo['name'].'</a>';
@ -681,9 +698,9 @@ function filemanager_file_explorer(
$data[1] = '<a href="'.$hack_metaconsole.'include/get_file.php?file='.urlencode($filename).'&hash='.$hash.'">'.$fileinfo['name'].'</a>';
}
// Notice that uploaded php files could be dangerous
if (pathinfo($fileinfo['realpath'], PATHINFO_EXTENSION) == 'php'
&& (is_readable($fileinfo['realpath']) || is_executable($fileinfo['realpath']))
// Notice that uploaded php files could be dangerous.
if (pathinfo($fileinfo['realpath'], PATHINFO_EXTENSION) === 'php'
&& (is_readable($fileinfo['realpath']) === true || is_executable($fileinfo['realpath']) === true)
) {
$error_message = __('This file could be executed by any user');
$error_message .= '. '.__('Make sure it can\'t perform dangerous tasks');
@ -702,12 +719,13 @@ function filemanager_file_explorer(
}
// Actions buttons
// Delete button
// Delete button.
$data[4] = '';
$data[4] .= '<span style="display: flex">';
$typefile = array_pop(explode('.', $fileinfo['name']));
if (is_writable($fileinfo['realpath'])
&& (! is_dir($fileinfo['realpath']) || count(scandir($fileinfo['realpath'])) < 3) && (!$readOnly)
if (is_writable($fileinfo['realpath']) === true
&& (is_dir($fileinfo['realpath']) === false || count(scandir($fileinfo['realpath'])) < 3)
&& ($readOnly === false)
) {
$data[4] .= '<form method="post" action="'.$url.'" style="">';
$data[4] .= '<input type="image" class="invert_filter" src="images/cross.png" onClick="if (!confirm(\' '.__('Are you sure?').'\')) return false;">';
@ -727,9 +745,9 @@ function filemanager_file_explorer(
$data[4] .= html_print_input_hidden('hash2', $hash2, true);
$data[4] .= '</form>';
if (($editor) && (!$readOnly)) {
if (($typefile != 'bin') && ($typefile != 'pdf') && ($typefile != 'png') && ($typefile != 'jpg')
&& ($typefile != 'iso') && ($typefile != 'docx') && ($typefile != 'doc') && ($fileinfo['mime'] != MIME_DIR)
if (($editor) && ($readOnly === false)) {
if (($typefile !== 'bin') && ($typefile !== 'pdf') && ($typefile !== 'png') && ($typefile !== 'jpg')
&& ($typefile !== 'iso') && ($typefile !== 'docx') && ($typefile !== 'doc') && ($fileinfo['mime'] != MIME_DIR)
) {
$hash = md5($fileinfo['realpath'].$config['server_unique_identifier']);
$data[4] .= "<a style='vertical-align: top;' href='$url&edit_file=1&hash=".$hash.'&location_file='.$fileinfo['realpath']."' style='float: left;'>".html_print_image('images/edit.png', true, ['style' => 'margin-top: 2px;', 'title' => __('Edit file'), 'class' => 'invert_filter']).'</a>';
@ -758,9 +776,9 @@ function filemanager_file_explorer(
);
}
if (!$readOnly) {
if (is_writable($real_directory)) {
// The buttons to make actions
if ($readOnly === false) {
if (is_writable($real_directory) === true) {
// The buttons to make actions.
$tabs_dialog = '<ul id="file_table_modal">
<li class="create_folder">
<a href="javascript: show_form_create_folder();">'.html_print_image(
@ -855,18 +873,17 @@ function filemanager_file_explorer(
/**
* Check if a directory is writable.
*
* @param string Directory path to check.
* @param bool If set, it will try to make the directory writeable if it's not.
* @param string $filepath Directory path to check.
*
* @param bool Wheter the directory is writeable or not.
* @return boolean Wheter the directory is writeable or not.
*/
function filemanager_get_file_info($filepath)
function filemanager_get_file_info(string $filepath)
{
global $config;
$realpath = realpath($filepath);
$filepath = str_replace('\\', '/', $filepath);
// Windows compatibility
// Windows compatibility.
$info = [
'mime' => MIME_UNKNOWN,
'mime_extend' => mime_content_type($filepath),
@ -904,10 +921,9 @@ function filemanager_get_file_info($filepath)
/**
* Check if a directory is writable.
*
* @param string Directory path to check.
* @param bool If set, it will try to make the directory writeable if it's not.
* @param string $dirpath Directory path to check.
*
* @param bool Wheter the directory is writeable or not.
* @return array List with files.
*/
function filemanager_list_dir($dirpath)
{
@ -917,8 +933,8 @@ function filemanager_list_dir($dirpath)
$dirs = [];
$dir = opendir($dirpath);
while ($file = @readdir($dir)) {
// Ignore hidden files
if ($file[0] == '.') {
// Ignore hidden files.
if ($file[0] === '.') {
continue;
}

View File

@ -65,23 +65,17 @@ if (isset($config['filemanager']['message'])) {
$config['filemanager']['message'] = null;
}
$directory = (string) get_parameter('directory', SNMP_DIR_MIBS);
$directory = (string) get_parameter('directory');
$directory = str_replace('\\', '/', $directory);
// Add custom directories here
$fallback_directory = 'attachment/mibs';
// Add custom directories here.
$fallback_directory = SNMP_DIR_MIBS;
// A miminal security check to avoid directory traversal
if (preg_match('/\.\./', $directory)) {
$directory = $fallback_directory;
}
if (preg_match('/^\//', $directory)) {
$directory = $fallback_directory;
}
if (preg_match('/^manager/', $directory)) {
if (empty($directory) === true) {
$directory = $fallback_directory;
} else {
$directory = str_replace('\\', '/', $directory);
$directory = filemanager_safe_directory($directory, $fallback_directory);
}
$banned_directories['include'] = true;
@ -91,13 +85,10 @@ $banned_directories['reporting'] = true;
$banned_directories['general'] = true;
$banned_directories[ENTERPRISE_DIR] = true;
if (isset($banned_directories[$directory])) {
if (isset($banned_directories[$directory]) === true) {
$directory = $fallback_directory;
}
// Current directory
$available_directories[$directory] = $directory;
$real_directory = realpath($config['homedir'].'/'.$directory);
ui_print_info_message(__('MIB files will be installed on the system. Please note that a MIB may depend on other MIB. To customize trap definitions use the SNMP trap editor.'));
@ -107,11 +98,11 @@ $create_text_file = (bool) get_parameter('create_text_file');
$default_real_directory = realpath($config['homedir'].'/'.$fallback_directory);
if ($upload_file_or_zip) {
if ($upload_file_or_zip === true) {
upload_file($upload_file_or_zip, $default_real_directory);
}
if ($create_text_file) {
if ($create_text_file === true) {
create_text_file($default_real_directory);
}