--- /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/github_19.0.3_basexml.php +++ /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/client_basexml.php @@ -0,0 +1,132 @@ +'; + + // Create the main "Connector" node. + echo ''; + + // Add the current folder node. + echo ''; + + $GLOBALS['HeaderSent'] = true; +} + +/** + * CreateXmlFooter + * + * @return void + */ +function CreateXmlFooter() +{ + echo ''; +} + +/** + * SendError + * + * @param integer $number Number + * @param unknown_type $text Text + * @return void + */ +function SendError($number, $text) +{ + if ($_GET['Command'] == 'FileUpload') + SendUploadResults($number, "", "", $text); + + if (isset($GLOBALS['HeaderSent']) && $GLOBALS['HeaderSent']) + { + SendErrorNode($number, $text); + CreateXmlFooter(); + } + else + { + SetXmlHeaders(); + + dol_syslog('Error: '.$number.' '.$text, LOG_ERR); + + // Create the XML document header + echo ''; + + echo ''; + + SendErrorNode($number, $text); + + echo ''; + } + exit; +} + +/** + * SendErrorNode + * + * @param integer $number Number + * @param string $text Text of error + * @return string Error node + */ +function SendErrorNode($number, $text) +{ + if ($text) + echo ''; + else + echo ''; +} --- /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/github_19.0.3_commands.php +++ /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/client_commands.php @@ -0,0 +1,329 @@ +'; + } + closedir($oCurrentFolder); + } + + // Open the "Folders" node. + echo ""; + + natcasesort($aFolders); + foreach ($aFolders as $sFolder) + echo $sFolder; + + // Close the "Folders" node. + echo ""; +} + +/** + * GetFoldersAndFiles + * + * @param string $resourceType Resource type + * @param string $currentFolder Current folder + * @return void + */ +function GetFoldersAndFiles($resourceType, $currentFolder) +{ + // Map the virtual path to the local server path. + $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'GetFoldersAndFiles'); + + // Arrays that will hold the folders and files names. + $aFolders = array(); + $aFiles = array(); + + $oCurrentFolder = @opendir($sServerDir); + + if ($oCurrentFolder !== false) + { + while ($sFile = readdir($oCurrentFolder)) + { + if ($sFile != '.' && $sFile != '..') + { + if (is_dir($sServerDir.$sFile)) + $aFolders[] = ''; + else + { + $iFileSize = @filesize($sServerDir.$sFile); + if (!$iFileSize) { + $iFileSize = 0; + } + if ($iFileSize > 0) + { + $iFileSize = round($iFileSize / 1024); + if ($iFileSize < 1) + $iFileSize = 1; + } + + $aFiles[] = ''; + } + } + } + closedir($oCurrentFolder); + } + + // Send the folders + natcasesort($aFolders); + echo ''; + + foreach ($aFolders as $sFolder) + echo $sFolder; + + echo ''; + + // Send the files + natcasesort($aFiles); + echo ''; + + foreach ($aFiles as $sFiles) + echo $sFiles; + + echo ''; +} + +/** + * Create folder + * + * @param string $resourceType Resource type + * @param string $currentFolder Current folder + * @return void + */ +function CreateFolder($resourceType, $currentFolder) +{ + if (!isset($_GET)) { + global $_GET; + } + $sErrorNumber = '0'; + $sErrorMsg = ''; + + if (isset($_GET['NewFolderName'])) + { + $sNewFolderName = $_GET['NewFolderName']; + $sNewFolderName = SanitizeFolderName($sNewFolderName); + + if (strpos($sNewFolderName, '..') !== false) + $sErrorNumber = '102'; // Invalid folder name. + else + { + // Map the virtual path to the local server path of the current folder. + $sServerDir = ServerMapFolder($resourceType, $currentFolder, 'CreateFolder'); + + if (is_writable($sServerDir)) + { + $sServerDir .= $sNewFolderName; + + $sErrorMsg = CreateServerFolder($sServerDir); + + switch ($sErrorMsg) + { + case '': + $sErrorNumber = '0'; + break; + case 'Invalid argument' : + case 'No such file or directory' : + $sErrorNumber = '102'; // Path too long. + break; + default: + $sErrorNumber = '110'; + break; + } + } + else + $sErrorNumber = '103'; + } + } + else + $sErrorNumber = '102'; + + // Create the "Error" node. + echo ''; +} + +// @CHANGE +//function FileUpload( $resourceType, $currentFolder, $sCommand ) +/** + * FileUpload + * + * @param string $resourceType Resource type + * @param string $currentFolder Current folder + * @param string $sCommand Command + * @param string $CKEcallback Callback + * @return null + */ +function FileUpload($resourceType, $currentFolder, $sCommand, $CKEcallback = '') +{ + if (!isset($_FILES)) { + global $_FILES; + } + $sErrorNumber = '0'; + $sFileName = ''; + + if (isset($_FILES['NewFile']) && !is_null($_FILES['NewFile']['tmp_name']) + // This is for the QuickUpload tab box + or (isset($_FILES['upload']) && !is_null($_FILES['upload']['tmp_name']))) + { + global $Config; + + $oFile = isset($_FILES['NewFile']) ? $_FILES['NewFile'] : $_FILES['upload']; + + // Map the virtual path to the local server path. + $sServerDir = ServerMapFolder($resourceType, $currentFolder, $sCommand); + + // Get the uploaded file name. + $sFileName = $oFile['name']; + $sFileName = SanitizeFileName($sFileName); + + $sOriginalFileName = $sFileName; + + // Get the extension. + $sExtension = substr($sFileName, (strrpos($sFileName, '.') + 1)); + $sExtension = strtolower($sExtension); + + if (isset($Config['SecureImageUploads'])) + { + if (($isImageValid = IsImageValid($oFile['tmp_name'], $sExtension)) === false) + { + $sErrorNumber = '202'; + } + } + + if (isset($Config['HtmlExtensions'])) + { + if (!IsHtmlExtension($sExtension, $Config['HtmlExtensions']) && + ($detectHtml = DetectHtml($oFile['tmp_name'])) === true) + { + $sErrorNumber = '202'; + } + } + + // Check if it is an allowed extension. + if (!$sErrorNumber && IsAllowedExt($sExtension, $resourceType)) + { + $iCounter = 0; + + while (true) + { + $sFilePath = $sServerDir.$sFileName; + + if (is_file($sFilePath)) + { + $iCounter++; + $sFileName = RemoveExtension($sOriginalFileName).'('.$iCounter.').'.$sExtension; + $sErrorNumber = '201'; + } + else + { + move_uploaded_file($oFile['tmp_name'], $sFilePath); + + if (is_file($sFilePath)) + { + if (isset($Config['ChmodOnUpload']) && !$Config['ChmodOnUpload']) + { + break; + } + + $permissions = '0777'; + if (isset($Config['ChmodOnUpload']) && $Config['ChmodOnUpload']) + { + $permissions = (string) $Config['ChmodOnUpload']; + } + $permissionsdec = octdec($permissions); + dol_syslog("commands.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec)); + $oldumask = umask(0); + chmod($sFilePath, $permissionsdec); + umask($oldumask); + } + + break; + } + } + + if (file_exists($sFilePath)) + { + //previous checks failed, try once again + if (isset($isImageValid) && $isImageValid === -1 && IsImageValid($sFilePath, $sExtension) === false) + { + @unlink($sFilePath); + $sErrorNumber = '202'; + } + elseif (isset($detectHtml) && $detectHtml === -1 && DetectHtml($sFilePath) === true) + { + @unlink($sFilePath); + $sErrorNumber = '202'; + } + } + } + else + $sErrorNumber = '202'; + } + else + $sErrorNumber = '202'; + + + $sFileUrl = CombinePaths(GetResourceTypePath($resourceType, $sCommand), $currentFolder); + $sFileUrl = CombinePaths($sFileUrl, $sFileName); + + + // @CHANGE + //SendUploadResults( $sErrorNumber, $sFileUrl, $sFileName ); + if ($CKEcallback == '') + { + // this line already exists so wrap the if block around it + SendUploadResults($sErrorNumber, $sFileUrl, $sFileName); + } + else + { + //issue the CKEditor Callback + SendCKEditorResults( + $CKEcallback, + $sFileUrl, + ($sErrorNumber != 0 ? 'Error '.$sErrorNumber.' upload failed.' : 'Upload Successful') + ); + } + + exit; +} --- /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/github_19.0.3_connector.php +++ /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/client_connector.php @@ -22 +22 @@ - * This is the File Manager Connector for PHP. It returns a XML file used by browser.php + * This is the File Manager Connector for PHP. @@ -27,2 +27,5 @@ -require 'config.inc.php'; // This include the main.inc.php -require 'connector.lib.php'; +require 'config.php'; +require 'util.php'; +require 'io.php'; +require 'basexml.php'; +require 'commands.php'; @@ -30,3 +33,2 @@ -if (!$Config['Enabled']) { - SendError(1, 'This connector is disabled. Please check the "editor/filemanager/connectors/php/config.inc.php" file'); -} +if (!$Config['Enabled']) + SendError(1, 'This connector is disabled. Please check the "editor/filemanager/connectors/php/config.php" file'); @@ -43,4 +45,4 @@ - if (!isset($_GET)) { - global $_GET; - } - if (!isset($_GET['Command']) || !isset($_GET['Type']) || !isset($_GET['CurrentFolder'])) { + if (!isset($_GET)) { + global $_GET; + } + if (!isset($_GET['Command']) || !isset($_GET['Type']) || !isset($_GET['CurrentFolder'])) @@ -48 +49,0 @@ - } @@ -56 +57,2 @@ - if (!IsAllowedCommand($sCommand)) { + if (!IsAllowedCommand($sCommand)) + { @@ -60 +62 @@ - if (!IsAllowedType($sResourceType)) { + if (!IsAllowedType($sResourceType)) @@ -62 +63,0 @@ - } @@ -65 +66,2 @@ - if ($sCommand == 'FileUpload') { + if ($sCommand == 'FileUpload') + { @@ -73,2 +75,3 @@ - switch ($sCommand) { - case 'GetFolders': + switch ($sCommand) + { + case 'GetFolders' : @@ -77 +80 @@ - case 'GetFoldersAndFiles': + case 'GetFoldersAndFiles' : @@ -80 +83 @@ - case 'CreateFolder': + case 'CreateFolder' : --- /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/github_19.0.3_io.php +++ /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/client_io.php @@ -0,0 +1,432 @@ + 0) + return $Config['QuickUploadAbsolutePath'][$resourceType]; + + // Map the "UserFiles" path to a local directory. + return Server_MapPath($Config['QuickUploadPath'][$resourceType]); + } + else + { + if (strlen($Config['FileTypesAbsolutePath'][$resourceType]) > 0) + return $Config['FileTypesAbsolutePath'][$resourceType]; + + // Map the "UserFiles" path to a local directory. + return Server_MapPath($Config['FileTypesPath'][$resourceType]); + } +} + +/** + * GetUrlFromPath + * + * @param string $resourceType Resource type + * @param string $folderPath Path + * @param string $sCommand Command + * @return string Full url + */ +function GetUrlFromPath($resourceType, $folderPath, $sCommand) +{ + return CombinePaths(GetResourceTypePath($resourceType, $sCommand), $folderPath); +} + +/** + * RemoveExtension + * + * @param string $fileName Filename + * @return string String without extension + */ +function RemoveExtension($fileName) +{ + return substr($fileName, 0, strrpos($fileName, '.')); +} +/** + * ServerMapFolder + * + * @param string $resourceType Resource type + * @param string $folderPath Folder + * @param string $sCommand Command + * @return string + */ +function ServerMapFolder($resourceType, $folderPath, $sCommand) +{ + // Get the resource type directory. + $sResourceTypePath = GetResourceTypeDirectory($resourceType, $sCommand); + + // Ensure that the directory exists. + $sErrorMsg = CreateServerFolder($sResourceTypePath); + if ($sErrorMsg != '') + SendError(1, "Error creating folder \"{$sResourceTypePath}\" ({$sErrorMsg})"); + + // Return the resource type directory combined with the required path. + return CombinePaths($sResourceTypePath, $folderPath); +} + +/** + * GetParentFolder + * + * @param string $folderPath Folder path + * @return string Parent folder + */ +function GetParentFolder($folderPath) +{ + $sPattern = "-[/\\\\][^/\\\\]+[/\\\\]?$-"; + return preg_replace($sPattern, '', $folderPath); +} + +/** + * CreateServerFolder + * + * @param string $folderPath Folder + * @param string $lastFolder Folder + * @return string ''=success, error message otherwise + */ +function CreateServerFolder($folderPath, $lastFolder = null) +{ + global $Config; + $sParent = GetParentFolder($folderPath); + + // Ensure the folder path has no double-slashes, or mkdir may fail on certain platforms + while (strpos($folderPath, '//') !== false) + { + $folderPath = str_replace('//', '/', $folderPath); + } + + // Check if the parent exists, or create it. + if (!empty($sParent) && !file_exists($sParent)) + { + //prevents agains infinite loop when we can't create root folder + if (!is_null($lastFolder) && $lastFolder === $sParent) { + return "Can't create $folderPath directory"; + } + + $sErrorMsg = CreateServerFolder($sParent, $folderPath); + if ($sErrorMsg != '') + return $sErrorMsg; + } + + if (!file_exists($folderPath)) + { + // Turn off all error reporting. + error_reporting(0); + + $php_errormsg = ''; + // Enable error tracking to catch the error. + ini_set('track_errors', '1'); + + if (isset($Config['ChmodOnFolderCreate']) && !$Config['ChmodOnFolderCreate']) + { + mkdir($folderPath); + } + else + { + $permissions = '0777'; + if (isset($Config['ChmodOnFolderCreate']) && $Config['ChmodOnFolderCreate']) + { + $permissions = (string) $Config['ChmodOnFolderCreate']; + } + $permissionsdec = octdec($permissions); + $permissionsdec |= octdec('0111'); // Set x bit required for directories + dol_syslog("io.php permission = ".$permissions." ".$permissionsdec." ".decoct($permissionsdec)); + // To create the folder with 0777 permissions, we need to set umask to zero. + $oldumask = umask(0); + mkdir($folderPath, $permissionsdec); + umask($oldumask); + } + + $sErrorMsg = $php_errormsg; + + // Restore the configurations. + ini_restore('track_errors'); + ini_restore('error_reporting'); + + return $sErrorMsg; + } + else + return ''; +} + +/** + * Get Root Path + * + * @return string real path + */ +function GetRootPath() +{ + if (!isset($_SERVER)) { + global $_SERVER; + } + $sRealPath = realpath('./'); + // #2124 ensure that no slash is at the end + $sRealPath = rtrim($sRealPath, "\\/"); + + $sSelfPath = $_SERVER['PHP_SELF']; + $sSelfPath = substr($sSelfPath, 0, strrpos($sSelfPath, '/')); + + $sSelfPath = str_replace('/', DIRECTORY_SEPARATOR, $sSelfPath); + + $position = strpos($sRealPath, $sSelfPath); + + // This can check only that this script isn't run from a virtual dir + // But it avoids the problems that arise if it isn't checked + if ($position === false || $position <> strlen($sRealPath) - strlen($sSelfPath)) + SendError(1, 'Sorry, can\'t map "UserFilesPath" to a physical path. You must set the "UserFilesAbsolutePath" value in "editor/filemanager/connectors/php/config.php".'); + + return substr($sRealPath, 0, $position); +} + +/** + * Emulate the asp Server.mapPath function. + * @param string $path given an url path return the physical directory that it corresponds to + * @return string Path + */ +function Server_MapPath($path) +{ + // This function is available only for Apache + if (function_exists('apache_lookup_uri')) { + $info = apache_lookup_uri($path); + return $info->filename.$info->path_info; + } + + // This isn't correct but for the moment there's no other solution + // If this script is under a virtual directory or symlink it will detect the problem and stop + return GetRootPath().$path; +} + +/** + * Is Allowed Extension + * + * @param string $sExtension File extension + * @param string $resourceType ressource type + * @return boolean true or false + */ +function IsAllowedExt($sExtension, $resourceType) +{ + global $Config; + // Get the allowed and denied extensions arrays. + $arAllowed = $Config['AllowedExtensions'][$resourceType]; + $arDenied = $Config['DeniedExtensions'][$resourceType]; + + if (count($arAllowed) > 0 && !in_array($sExtension, $arAllowed)) + return false; + + if (count($arDenied) > 0 && in_array($sExtension, $arDenied)) + return false; + + return true; +} + +/** + * Is Allowed Type + * + * @param string $resourceType ressource type + * @return boolean true or false + */ +function IsAllowedType($resourceType) +{ + global $Config; + if (!in_array($resourceType, $Config['ConfigAllowedTypes'])) + return false; + + return true; +} + +/** + * IsAllowedCommand + * + * @param string $sCommand Command + * @return boolean True or false + */ +function IsAllowedCommand($sCommand) +{ + global $Config; + + if (!in_array($sCommand, $Config['ConfigAllowedCommands'])) + return false; + + return true; +} + +/** + * GetCurrentFolder + * + * @return string current folder + */ +function GetCurrentFolder() +{ + if (!isset($_GET)) { + global $_GET; + } + $sCurrentFolder = isset($_GET['CurrentFolder']) ? GETPOST('CurrentFolder', '', 1) : '/'; + + // Check the current folder syntax (must begin and start with a slash). + if (!preg_match('|/$|', $sCurrentFolder)) + $sCurrentFolder .= '/'; + if (strpos($sCurrentFolder, '/') !== 0) + $sCurrentFolder = '/'.$sCurrentFolder; + + // Ensure the folder path has no double-slashes + while (strpos($sCurrentFolder, '//') !== false) { + $sCurrentFolder = str_replace('//', '/', $sCurrentFolder); + } + + // Check for invalid folder paths (..) + if (strpos($sCurrentFolder, '..') || strpos($sCurrentFolder, "\\")) + SendError(102, ''); + + if (preg_match(",(/\.)|[[:cntrl:]]|(//)|(\\\\)|([\:\*\?\"\<\>\|]),", $sCurrentFolder)) + SendError(102, ''); + + return $sCurrentFolder; +} + +/** + * Do a cleanup of the folder name to avoid possible problems + * + * @param string $sNewFolderName Folder + * @return string Folder sanitized + */ +function SanitizeFolderName($sNewFolderName) +{ + $sNewFolderName = stripslashes($sNewFolderName); + + // Remove . \ / | : ? * " < > + $sNewFolderName = preg_replace('/\\.|\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFolderName); + + return $sNewFolderName; +} + +/** + * Do a cleanup of the file name to avoid possible problems + * + * @param string $sNewFileName Folder + * @return string Folder sanitized + */ +function SanitizeFileName($sNewFileName) +{ + global $Config; + + $sNewFileName = stripslashes($sNewFileName); + + // Replace dots in the name with underscores (only one dot can be there... security issue). + if ($Config['ForceSingleExtension']) + $sNewFileName = preg_replace('/\\.(?![^.]*$)/', '_', $sNewFileName); + + // Remove \ / | : ? * " < > + $sNewFileName = preg_replace('/\\\\|\\/|\\||\\:|\\?|\\*|"|<|>|[[:cntrl:]]/', '_', $sNewFileName); + + return $sNewFileName; +} + +/** + * This is the function that sends the results of the uploading process. + * + * @param string $errorNumber errorNumber + * @param string $fileUrl fileUrl + * @param string $fileName fileName + * @param string $customMsg customMsg + * @return void + */ +function SendUploadResults($errorNumber, $fileUrl = '', $fileName = '', $customMsg = '') +{ + // Minified version of the document.domain automatic fix script (#1919). + // The original script can be found at _dev/domain_fix_template.js + echo << +(function(){var d=document.domain;while (true){try{var A=window.parent.document.domain;break;}catch(e) {};d=d.replace(/.*?(?:\.|$)/,'');if (d.length==0) break;try{document.domain=d;}catch (e){break;}}})(); +EOF; + + if ($errorNumber && $errorNumber != 201) { + $fileUrl = ""; + $fileName = ""; + } + + $rpl = array('\\' => '\\\\', '"' => '\\"'); + echo 'window.parent.OnUploadCompleted('.$errorNumber.',"'.strtr($fileUrl, $rpl).'","'.strtr($fileName, $rpl).'", "'.strtr($customMsg, $rpl).'");'; + echo ''; + exit; +} + + +// @CHANGE + +// This is the function that sends the results of the uploading process to CKE. +/** + * SendCKEditorResults + * + * @param string $callback callback + * @param string $sFileUrl sFileUrl + * @param string $customMsg customMsg + * @return void + */ +function SendCKEditorResults($callback, $sFileUrl, $customMsg = '') +{ + echo ''; +} --- /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/github_19.0.3_util.php +++ /tmp/dsg/dolibarr/htdocs/core/filemanagerdol/connectors/php/client_util.php @@ -0,0 +1,234 @@ + $val) + { + $lcaseHtmlExtensions[$key] = strtolower($val); + } + return in_array($ext, $lcaseHtmlExtensions); +} + +/** + * Detect HTML in the first KB to prevent against potential security issue with + * IE/Safari/Opera file type auto detection bug. + * Returns true if file contain insecure HTML code at the beginning. + * + * @param string $filePath absolute path to file + * @return boolean + */ +function DetectHtml($filePath) +{ + $fp = @fopen($filePath, 'rb'); + + //open_basedir restriction, see #1906 + if ($fp === false || !flock($fp, LOCK_SH)) + { + return -1; + } + + $chunk = fread($fp, 1024); + flock($fp, LOCK_UN); + fclose($fp); + + $chunk = strtolower($chunk); + + if (!$chunk) + { + return false; + } + + $chunk = trim($chunk); + + if (preg_match("/