/** * Upload files * * @since 1.0 */ function upload() { // Check for request forgeries JRequest::checkToken('request') or jexit('Invalid Token'); $user = JFactory::getUser(); $app = JFactory::getApplication(); $task = JRequest::getVar('task'); // calculate access $canupload = $user->authorise('flexicontent.uploadfiles', 'com_flexicontent'); $is_authorised = $canupload; // check access if (!$is_authorised) { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "' . JText::_('FLEXI_ALERTNOTAUTH') . '"}, "id" : "id"}'); } else { JError::raiseNotice(403, JText::_('FLEXI_ALERTNOTAUTH')); $this->setRedirect('index.php?option=com_flexicontent&view=filemanager', ''); } return; } $option = JRequest::getVar('option'); if ($task == 'uploads') { $file = JRequest::getVar('file', '', 'files', 'array'); } else { // Default field <input type="file" is name="Filedata" ... get the file $ffname = JRequest::getCmd('file-ffname', 'Filedata', 'post'); $file = JRequest::getVar($ffname, '', 'files', 'array'); // Refactor the array swapping positions $file = $this->refactorFilesArray($file); // Get nested position, and reach the final file data array $fname_level1 = JRequest::getCmd('fname_level1', null, 'post'); $fname_level2 = JRequest::getCmd('fname_level2', null, 'post'); $fname_level3 = JRequest::getCmd('fname_level3', null, 'post'); if (strlen($fname_level1)) { $file = $file[$fname_level1]; } if (strlen($fname_level2)) { $file = $file[$fname_level2]; } if (strlen($fname_level3)) { $file = $file[$fname_level3]; } } $format = JRequest::getVar('format', 'html', '', 'cmd'); $secure = JRequest::getInt('secure', 1); $secure = $secure ? 1 : 0; $return = JRequest::getVar('return-url', null, '', 'base64'); $filetitle = JRequest::getVar('file-title', ''); $filedesc = JRequest::getVar('file-desc', ''); $filelang = JRequest::getVar('file-lang', ''); $fieldid = JRequest::getVar('fieldid', 0); $u_item_id = JRequest::getVar('u_item_id', 0); $file_mode = JRequest::getVar('folder_mode', 0) ? 'folder_mode' : 'db_mode'; $err = null; $model = $this->getModel('filemanager'); if ($file_mode != 'folder_mode' && $fieldid) { // Check if FORCED secure/media mode parameter exists and if it is forced $field_params = $model->getFieldParams($fieldid); $target_dir = $field_params->get('target_dir', ''); if (strlen($target_dir) && $target_dir != 2) { $secure = $target_dir ? 1 : 0; // force secure / media } else { // allow filter secure via form/URL variable } } // ***************************************** // Check that a file was provided / uploaded // ***************************************** if (!isset($file['name'])) { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "' . JText::_('Filename has invalid characters (or other error occured)') . '"}, "id" : "id"}'); } else { JError::raiseWarning(100, JText::_('Filename has invalid characters (or other error occured)')); $this->setRedirect($_SERVER['HTTP_REFERER'], ''); } return; } // Chunking might be enabled $chunks = JRequest::getInt('chunks'); if ($chunks) { $chunk = JRequest::getInt('chunk'); // Get / Create target directory $targetDir = (ini_get("upload_tmp_dir") ? ini_get("upload_tmp_dir") : sys_get_temp_dir()) . DIRECTORY_SEPARATOR . "fc_fileselement"; if (!file_exists($targetDir)) { @mkdir($targetDir); } // Create name of the unique temporary filename to use for concatenation of the chunks, or get the filename from session $fileName = JRequest::getVar('filename'); $fileName_tmp = $app->getUserState($fileName, date('Y_m_d_') . uniqid()); $app->setUserState($fileName, $fileName_tmp); $filePath_tmp = $targetDir . DIRECTORY_SEPARATOR . $fileName_tmp; // Open temp file if (!($out = @fopen("{$filePath_tmp}", "ab"))) { die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream: ' . $fileName_tmp . '."}, "id" : "id"}'); } if (!empty($_FILES)) { if ($_FILES["file"]["error"] || !is_uploaded_file($_FILES["file"]["tmp_name"])) { die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}'); } if (!($in = @fopen($_FILES["file"]["tmp_name"], "rb"))) { die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); } } else { if (!($in = @fopen("php://input", "rb"))) { die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); } } // Read binary input stream and append it to temp file while ($buff = fread($in, 4096)) { fwrite($out, $buff); } @fclose($out); @fclose($in); // If not last chunk terminate further execution if ($chunk < $chunks - 1) { // Return Success JSON-RPC response die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); } $app->setUserState($fileName, null); // Cleanup left-over files if (file_exists($targetDir)) { foreach (new DirectoryIterator($targetDir) as $fileInfo) { if ($fileInfo->isDot()) { continue; } if (time() - $fileInfo->getCTime() >= 60) { unlink($fileInfo->getRealPath()); } } } //echo "-- chunk: $chunk \n-- chunks: $chunks \n-- targetDir: $targetDir \n--filePath_tmp: $filePath_tmp \n--fileName: $fileName"; //echo "\n"; print_r($_REQUEST); $file['name'] = $fileName; $file['tmp_name'] = $filePath_tmp; $file['size'] = filesize($filePath_tmp); $file['error'] = 0; //echo "\n"; print_r($file); } if ($file_mode == 'folder_mode') { $upload_path_var = 'fc_upload_path_' . $fieldid . '_' . $u_item_id; $path = $app->getUserState($upload_path_var, '') . DS; if ($task != 'uploads') { $app->setUserState($upload_path_var, ''); } // Do not clear in multi-upload } else { $path = $secure ? COM_FLEXICONTENT_FILEPATH . DS : COM_FLEXICONTENT_MEDIAPATH . DS; } jimport('joomla.utilities.date'); // Set FTP credentials, if given jimport('joomla.client.helper'); JClientHelper::setCredentialsFromRequest('ftp'); // Make the filename safe jimport('joomla.filesystem.file'); // Sanitize filename further and make unique $params = null; $filename_original = strip_tags($file['name']); // Store original filename before sanitizing the filename $upload_check = flexicontent_upload::check($file, $err, $params); $filename = flexicontent_upload::sanitize($path, $file['name']); $filepath = JPath::clean($path . strtolower($filename)); // Check if uploaded file is valid if (!$upload_check) { if ($format == 'json') { jimport('joomla.error.log'); $log = JLog::getInstance('com_flexicontent.error.php'); $log->addEntry(array('comment' => 'Invalid: ' . $filepath . ': ' . $err)); header('HTTP/1.0 415 Unsupported Media Type'); if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Error. Unsupported Media Type!"}, "id" : "id"}'); } else { die('Error. Unsupported Media Type!'); } } else { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 104, "message": "' . $err . '"}, "id" : "id"}'); } else { JError::raiseNotice(100, JText::_($err)); // REDIRECT if ($return) { $app->redirect(base64_decode($return) . "&" . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . "=1"); } } return; } } // Get the extension to record it in the DB $ext = strtolower(flexicontent_upload::getExt($filename)); // Upload Failed //echo "\n". $file['tmp_name'] ." => ". $filepath ."\n"; $move_success = $chunks ? rename($file['tmp_name'], $filepath) : JFile::upload($file['tmp_name'], $filepath); if (!$move_success) { if ($format == 'json') { jimport('joomla.error.log'); $log = JLog::getInstance('com_flexicontent.error.php'); $log->addEntry(array('comment' => 'Cannot upload: ' . $filepath)); header('HTTP/1.0 409 Conflict'); if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 105, "message": "File already exists"}, "id" : "id"}'); } else { jexit('Error. File already exists'); } } else { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 106, "message": "' . JText::_('FLEXI_UNABLE_TO_UPLOAD_FILE') . '"}, "id" : "id"}'); } else { JError::raiseWarning(100, JText::_('FLEXI_UNABLE_TO_UPLOAD_FILE')); // REDIRECT if ($return) { $app->redirect(base64_decode($return) . "&" . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . "=1"); } } return; } // Upload Successful } else { // a. Database mode if ($file_mode == 'db_mode') { if ($format == 'json') { jimport('joomla.error.log'); $log = JLog::getInstance(); $log->addEntry(array('comment' => $filepath)); } $db = JFactory::getDBO(); $user = JFactory::getUser(); $path = $secure ? COM_FLEXICONTENT_FILEPATH . DS : COM_FLEXICONTENT_MEDIAPATH . DS; // JPATH_ROOT . DS . <media_path | file_path> . DS $filepath = $path . $filename; $filesize = file_exists($filepath) ? filesize($filepath) : 0; $obj = new stdClass(); $obj->filename = $filename; $obj->filename_original = $filename_original; $obj->altname = $filetitle ? $filetitle : $filename_original; $obj->url = 0; $obj->secure = $secure; $obj->ext = $ext; $obj->hits = 0; $obj->size = $filesize; $obj->description = $filedesc; $obj->language = $filelang ? $filelang : '*'; $obj->uploaded = JFactory::getDate('now')->toSql(); $obj->uploaded_by = $user->get('id'); // Insert file record in DB $db->insertObject('#__flexicontent_files', $obj); // Get id of new file record $file_id = (int) $db->insertid(); $option = JRequest::getVar('option'); $filter_item = $app->getUserStateFromRequest($option . '.fileselement.item_id', 'item_id', '', 'int'); if ($filter_item) { $session = JFactory::getSession(); $files = $session->get('fileselement.' . $filter_item, null); if (!$files) { $files = array(); } $files[] = $db->insertid(); $session->set('fileselement.' . $filter_item, $files); } // b. Custom Folder mode } else { $file_id = 0; } // JSON output: Terminate printing a message if ($format == 'json') { if ($task == 'uploads') { // Return Success JSON-RPC response die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); } else { jexit('Upload complete'); } // Normal output: Redirect setting a message } else { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); } else { $app->enqueueMessage(JText::_('FLEXI_UPLOAD_COMPLETE')); if (!$return) { return $file_id; } // No return URL, return the file ID $this->setRedirect(base64_decode($return) . "&newfileid=" . $file_id . "&newfilename=" . base64_encode($filename) . "&" . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . "=1", ''); } } } }
/** * Checks uploaded file * * @param string $file The file name * @param string $err Set (return) the error string in it * @param string $file view 's parameters * @return string The file extension * @since 1.5 */ static function check(&$file, &$err, &$params) { if (!$params) { $params = JComponentHelper::getParams('com_flexicontent'); } if (empty($file['name'])) { $err = 'FLEXI_PLEASE_INPUT_A_FILE'; return false; } jimport('joomla.filesystem.file'); $file['altname'] = $file['name']; if ($file['name'] !== JFile::makesafe($file['name'])) { //$err = JText::_('FLEXI_WARNFILENAME').','.$file['name'].'|'.JFile::makesafe($file['name'])."<br/>"; //return false; $file['name'] = date('Y-m-d-H-i-s') . "." . flexicontent_upload::getExt($file['name']); } // *************************************** // Check if the image file type is allowed // *************************************** $format = strtolower(flexicontent_upload::getExt($file['name'])); $allowed_exts = $params->get('upload_extensions', 'bmp,csv,doc,docx,gif,ico,jpg,jpeg,odg,odp,ods,odt,pdf,png,ppt,pptx,swf,txt,xcf,xls,xlsx,zip,ics'); $allowed_exts = preg_split("/[\\s]*,[\\s]*/", $allowed_exts); foreach ($allowed_exts as $a => $allowed_ext) { $allowed_exts[$a] = strtolower($allowed_ext); } $ignored = explode(',', $params->get('ignore_extensions')); foreach ($ignored as $a => $ignored_ext) { $ignored[$a] = strtolower($ignored_ext); } if (!in_array($format, $allowed_exts) && !in_array($format, $ignored)) { $err = 'FLEXI_WARNFILETYPE'; return false; } // ************** // Check filesize // ************** $maxSize = (int) $params->get('upload_maxsize', 0); if ($maxSize > 0 && (int) $file['size'] > $maxSize) { $err = 'FLEXI_WARNFILETOOLARGE'; return false; } $imginfo = null; $images = explode(',', $params->get('image_extensions')); if ($params->get('restrict_uploads', 1)) { if (in_array($format, $images)) { // if its an image run it through getimagesize if (($imginfo = getimagesize($file['tmp_name'])) === FALSE) { $err = 'FLEXI_WARNINVALIDIMG'; return false; } } else { if (!in_array($format, $ignored)) { // if its not an image...and we're not ignoring it $allowed_mime = explode(',', $params->get('upload_mime')); $illegal_mime = explode(',', $params->get('upload_mime_illegal')); if (function_exists('finfo_open') && $params->get('check_mime', 1)) { // We have fileinfo $finfo = finfo_open(FILEINFO_MIME); $type = finfo_file($finfo, $file['tmp_name']); if (strlen($type) && !in_array($type, $allowed_mime) && in_array($type, $illegal_mime)) { $err = 'FLEXI_WARNINVALIDMIME'; return false; } finfo_close($finfo); } else { if (function_exists('mime_content_type') && $params->get('check_mime', 1)) { // we have mime magic $type = mime_content_type($file['tmp_name']); if (strlen($type) && !in_array($type, $allowed_mime) && in_array($type, $illegal_mime)) { $err = 'FLEXI_WARNINVALIDMIME'; return false; } } } } } } // *************************** // Check fof XSS safe contents // *************************** $xss_check = JFile::read($file['tmp_name'], false, 256); $html_tags = array('abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote', 'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing', 'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option', 'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml', 'xmp', '!DOCTYPE', '!--'); foreach ($html_tags as $tag) { // A tag is '<tagname ', so we need to add < and a space or '<tagname>' if (stristr($xss_check, '<' . $tag . ' ') || stristr($xss_check, '<' . $tag . '>')) { $err = 'FLEXI_WARNIEXSS'; return false; } } return true; }
/** * Upload files * * @since 1.0 */ function upload() { // Check for request forgeries JRequest::checkToken('request') or jexit('Invalid Token'); $user = JFactory::getUser(); $app = JFactory::getApplication(); $task = JRequest::getVar('task'); $option = JRequest::getVar('option'); if ($task == 'uploads') { $file = JRequest::getVar('file', '', 'files', 'array'); } else { $file = JRequest::getVar('Filedata', '', 'files', 'array'); } $format = JRequest::getVar('format', 'html', '', 'cmd'); $secure = JRequest::getVar('secure', 1, '', 'int'); $return = JRequest::getVar('return-url', null, 'post', 'base64'); $filetitle = JRequest::getVar('file-title', ''); $filedesc = JRequest::getVar('file-desc', ''); $filelang = JRequest::getVar('file-lang', ''); $fieldid = JRequest::getVar('fieldid', 0); $u_item_id = JRequest::getVar('u_item_id', 0); $file_mode = JRequest::getVar('folder_mode', 0) ? 'folder_mode' : 'db_mode'; $err = null; // ***************************************** // Check that a file was provided / uploaded // ***************************************** if (!isset($file['name'])) { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "' . JText::_('Filename has invalid characters (or other error occured)') . '"}, "id" : "id"}'); } else { JError::raiseWarning(100, JText::_('Filename has invalid characters (or other error occured)')); $this->setRedirect($_SERVER['HTTP_REFERER'], ''); } return; } if ($file_mode == 'folder_mode') { $upload_path_var = 'fc_upload_path_' . $fieldid . '_' . $u_item_id; $path = $app->getUserState($upload_path_var, '') . DS; if ($task != 'uploads') { $app->setUserState($upload_path_var, ''); } // Do not clear in multi-upload } else { $path = $secure ? COM_FLEXICONTENT_FILEPATH . DS : COM_FLEXICONTENT_MEDIAPATH . DS; } jimport('joomla.utilities.date'); // Set FTP credentials, if given jimport('joomla.client.helper'); JClientHelper::setCredentialsFromRequest('ftp'); // Make the filename safe jimport('joomla.filesystem.file'); // Sanitize filename further and make unique $params = null; $filename_original = strip_tags($file['name']); // Store original filename before sanitizing the filename $upload_check = flexicontent_upload::check($file, $err, $params); $filename = flexicontent_upload::sanitize($path, $file['name']); $filepath = JPath::clean($path . strtolower($filename)); // Check if uploaded file is valid if (!$upload_check) { if ($format == 'json') { jimport('joomla.error.log'); $log = JLog::getInstance('com_flexicontent.error.php'); $log->addEntry(array('comment' => 'Invalid: ' . $filepath . ': ' . $err)); header('HTTP/1.0 415 Unsupported Media Type'); if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Error. Unsupported Media Type!"}, "id" : "id"}'); } else { die('Error. Unsupported Media Type!'); } } else { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 104, "message": "' . $err . '"}, "id" : "id"}'); } else { JError::raiseNotice(100, JText::_($err)); // REDIRECT if ($return) { $app->redirect(base64_decode($return) . "&" . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . "=1"); } } return; } } // Get the extension to record it in the DB $ext = strtolower(flexicontent_upload::getExt($filename)); // Upload Failed if (!JFile::upload($file['tmp_name'], $filepath)) { if ($format == 'json') { jimport('joomla.error.log'); $log = JLog::getInstance('com_flexicontent.error.php'); $log->addEntry(array('comment' => 'Cannot upload: ' . $filepath)); header('HTTP/1.0 409 Conflict'); if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 105, "message": "File already exists"}, "id" : "id"}'); } else { jexit('Error. File already exists'); } } else { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "error" : {"code": 106, "message": "' . JText::_('FLEXI_UNABLE_TO_UPLOAD_FILE') . '"}, "id" : "id"}'); } else { JError::raiseWarning(100, JText::_('FLEXI_UNABLE_TO_UPLOAD_FILE')); // REDIRECT if ($return) { $app->redirect(base64_decode($return) . "&" . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . "=1"); } } return; } // Upload Successful } else { // a. Database mode if ($file_mode == 'db_mode') { if ($format == 'json') { jimport('joomla.error.log'); $log = JLog::getInstance(); $log->addEntry(array('comment' => $filepath)); } $db = JFactory::getDBO(); $user = JFactory::getUser(); $config = JFactory::getConfig(); $date = JFactory::getDate('now'); $obj = new stdClass(); $obj->filename = $filename; $obj->filename_original = $filename_original; $obj->altname = $filetitle ? $filetitle : $filename_original; $obj->url = 0; $obj->secure = $secure; $obj->ext = $ext; $obj->hits = 0; $obj->description = $filedesc; $obj->language = $filelang ? $filelang : '*'; $obj->uploaded = FLEXI_J16GE ? $date->toSql() : $date->toMySQL(); $obj->uploaded_by = $user->get('id'); // Insert file record in DB $db->insertObject('#__flexicontent_files', $obj); // Get id of new file record $file_id = (int) $db->insertid(); $option = JRequest::getVar('option'); $filter_item = $app->getUserStateFromRequest($option . '.fileselement.item_id', 'item_id', '', 'int'); if ($filter_item) { $session = JFactory::getSession(); $files = $session->get('fileselement.' . $filter_item, null); if (!$files) { $files = array(); } $files[] = $db->insertid(); $session->set('fileselement.' . $filter_item, $files); } // b. Custom Folder mode } else { $file_id = 0; } // JSON output: Terminate printing a message if ($format == 'json') { if ($task == 'uploads') { // Return Success JSON-RPC response die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); } else { jexit('Upload complete'); } // Normal output: Redirect setting a message } else { if ($task == 'uploads') { die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); } else { $app->enqueueMessage(JText::_('FLEXI_UPLOAD_COMPLETE')); if (!$return) { return; } // No return URL $app->redirect(base64_decode($return) . "&newfileid=" . $file_id . "&newfilename=" . base64_encode($filename) . "&" . (FLEXI_J30GE ? JSession::getFormToken() : JUtility::getToken()) . "=1"); } } } }