Esempio n. 1
0
/**
 * Get is current user crawler
 *
 * @param string $agent if set, use this value instead HTTP_USER_AGENT
 * @return bool
 */
function isCrawler($agent = NULL)
{
    return Rhymix\Framework\UA::isRobot($agent);
}
Esempio n. 2
0
 public function procFileOutput()
 {
     // Get requsted file info
     $oFileModel = getModel('file');
     $file_srl = Context::get('file_srl');
     $file_key = Context::get('file_key');
     $columnList = array('source_filename', 'uploaded_filename', 'file_size');
     $file_obj = $oFileModel->getFile($file_srl, $columnList);
     $filesize = $file_obj->file_size;
     $filename = $file_obj->source_filename;
     $etag = md5($file_srl . $file_key . $_SERVER['HTTP_USER_AGENT']);
     // Check file key
     if (strlen($file_key) != 32 || !isset($_SESSION['__XE_FILE_KEY__']) || !is_string($_SESSION['__XE_FILE_KEY__'])) {
         return $this->stop('msg_invalid_request');
     }
     $file_key_data = $file_srl . $file_obj->file_size . $file_obj->uploaded_filename . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'];
     $file_key_compare = substr(hash_hmac('sha256', $file_key_data, $_SESSION['__XE_FILE_KEY__']), 0, 32);
     if ($file_key !== $file_key_compare) {
         return $this->stop('msg_invalid_request');
     }
     // Check if file exists
     $uploaded_filename = $file_obj->uploaded_filename;
     if (!file_exists($uploaded_filename)) {
         return $this->stop('msg_file_not_found');
     }
     // If client sent an If-None-Match header with the correct ETag, do not download again
     if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim(trim($_SERVER['HTTP_IF_NONE_MATCH']), '\'"') === $etag) {
         header('HTTP/1.1 304 Not Modified');
         exit;
     }
     // If client sent an If-Modified-Since header with a recent modification date, do not download again
     if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) > filemtime($uploaded_filename)) {
         header('HTTP/1.1 304 Not Modified');
         exit;
     }
     // Encode the filename.
     $filename_param = Rhymix\Framework\UA::encodeFilenameForDownload($filename);
     // Close context to prevent blocking the session
     Context::close();
     // Open file
     $fp = fopen($uploaded_filename, 'rb');
     if (!$fp) {
         return $this->stop('msg_file_not_found');
     }
     // Take care of pause and resume
     if (isset($_SERVER['HTTP_RANGE']) && preg_match('/^bytes=(\\d+)-(\\d+)?/', $_SERVER['HTTP_RANGE'], $matches)) {
         $range_start = $matches[1];
         $range_end = $matches[2] ? $matches[2] : $filesize - 1;
         $range_length = $range_end - $range_start + 1;
         if ($range_length < 1 || $range_start < 0 || $range_start >= $filesize || $range_end >= $filesize) {
             header('HTTP/1.1 416 Requested Range Not Satisfiable');
             fclose($fp);
             exit;
         }
         fseek($fp, $range_start);
         header('HTTP/1.1 206 Partial Content');
         header('Content-Range: bytes ' . $range_start . '-' . $range_end . '/' . $filesize);
     } else {
         $range_start = 0;
         $range_length = $filesize - $range_start;
     }
     // Clear buffer
     while (ob_get_level()) {
         ob_end_clean();
     }
     // Set headers
     header("Cache-Control: private; max-age=3600");
     header("Pragma: ");
     header("Content-Type: application/octet-stream");
     header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
     header('Content-Disposition: attachment; ' . $filename_param);
     header('Content-Transfer-Encoding: binary');
     header('Content-Length: ' . $range_length);
     header('Accept-Ranges: bytes');
     header('Etag: "' . $etag . '"');
     // Print the file contents
     for ($offset = 0; $offset < $range_length; $offset += 4096) {
         $buffer_size = min(4096, $range_length - $offset);
         echo fread($fp, $buffer_size);
         flush();
     }
     exit;
 }
Esempio n. 3
0
 /**
  * Check if user-agent is a tablet PC as iPad or Andoid tablet.
  *
  * @return bool TRUE for tablet, and FALSE for else.
  */
 public static function isMobilePadCheckByAgent()
 {
     return Rhymix\Framework\UA::isTablet();
 }
Esempio n. 4
0
 /**
  * Single Sign On (SSO)
  *
  * @return bool True : Module handling is necessary in the control path of current request , False : Otherwise
  */
 public function checkSSO()
 {
     // pass if it's not GET request or XE is not yet installed
     if (!config('use_sso') || Rhymix\Framework\UA::isRobot()) {
         return TRUE;
     }
     $checkActList = array('rss' => 1, 'atom' => 1);
     if (self::getRequestMethod() != 'GET' || !self::isInstalled() || isset($checkActList[self::get('act')])) {
         return TRUE;
     }
     // pass if default URL is not set
     $default_url = trim($this->db_info->default_url);
     if (!$default_url) {
         return TRUE;
     }
     if (substr_compare($default_url, '/', -1) !== 0) {
         $default_url .= '/';
     }
     // Get current site information (only the base URL, not the full URL)
     $current_site = self::getRequestUri();
     // Step 1: if the current site is not the default site, send SSO validation request to the default site
     if ($default_url !== $current_site && !self::get('sso_response') && $_COOKIE['sso'] !== md5($current_site)) {
         // Set sso cookie to prevent multiple simultaneous SSO validation requests
         setcookie('sso', md5($current_site), 0, '/');
         // Redirect to the default site
         $sso_request = Rhymix\Framework\Security::encrypt(Rhymix\Framework\URL::getCurrentURL());
         $redirect_url = $default_url . '?sso_request=' . urlencode($sso_request);
         header('Location:' . $redirect_url);
         return false;
     }
     // Step 2: receive and process SSO validation request at the default site
     if ($default_url === $current_site && self::get('sso_request')) {
         // Get the URL of the origin site
         $sso_request = Rhymix\Framework\Security::decrypt(self::get('sso_request'));
         if (!$sso_request || !preg_match('!^https?://!', $sso_request)) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
             return false;
         }
         // Check that the origin site is a valid site in this XE installation (to prevent open redirect vuln)
         if (!getModel('module')->getSiteInfoByDomain(rtrim($url, '/'))->site_srl) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Request', 400);
             return false;
         }
         // Redirect back to the origin site
         $sso_response = Rhymix\Framework\Security::encrypt(session_id());
         header('Location: ' . Rhymix\Framework\URL::modifyURL($sso_request, array('sso_response' => $sso_response)));
         return false;
     }
     // Step 3: back at the origin site, set session ID to be the same as the default site
     if ($default_url !== $current_site && self::get('sso_response')) {
         // Check SSO response
         $sso_response = Rhymix\Framework\Security::decrypt(self::get('sso_response'));
         if ($sso_response === false) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
             return false;
         }
         // Check that the response was given by the default site (to prevent session fixation CSRF)
         if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $default_url) !== 0) {
             self::displayErrorPage('SSO Error', 'Invalid SSO Response', 400);
             return false;
         }
         // Set session ID
         setcookie(session_name(), $sso_response);
         // Finally, redirect to the originally requested URL
         header('Location: ' . Rhymix\Framework\URL::getCurrentURL(array('sso_response' => null)));
         return false;
     }
     // If none of the conditions above apply, proceed normally
     return TRUE;
 }
Esempio n. 5
0
 /**
  * get a module instance and execute an action
  * @return ModuleObject executed module instance
  * */
 public function procModule()
 {
     $oModuleModel = getModel('module');
     $display_mode = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
     // If error occurred while preparation, return a message instance
     if ($this->error) {
         self::_setInputErrorToContext();
         $oMessageObject = self::getModuleInstance('message', $display_mode);
         $oMessageObject->setError(-1);
         $oMessageObject->setMessage($this->error);
         $oMessageObject->dispMessage();
         if ($this->httpStatusCode) {
             $oMessageObject->setHttpStatusCode($this->httpStatusCode);
         }
         return $oMessageObject;
     }
     // Get action information with conf/module.xml
     $xml_info = $oModuleModel->getModuleActionXml($this->module);
     // If not installed yet, modify act
     if ($this->module == "install") {
         if (!$this->act || !$xml_info->action->{$this->act}) {
             $this->act = $xml_info->default_index_act;
         }
     }
     // if act exists, find type of the action, if not use default index act
     if (!$this->act) {
         $this->act = $xml_info->default_index_act;
     }
     // still no act means error
     if (!$this->act) {
         $this->error = 'msg_module_is_not_exists';
         $this->httpStatusCode = '404';
         self::_setInputErrorToContext();
         $oMessageObject = self::getModuleInstance('message', $display_mode);
         $oMessageObject->setError(-1);
         $oMessageObject->setMessage($this->error);
         $oMessageObject->dispMessage();
         if ($this->httpStatusCode) {
             $oMessageObject->setHttpStatusCode($this->httpStatusCode);
         }
         return $oMessageObject;
     }
     // get type, kind
     $type = $xml_info->action->{$this->act}->type;
     $ruleset = $xml_info->action->{$this->act}->ruleset;
     $kind = stripos($this->act, 'admin') !== FALSE ? 'admin' : '';
     if (!$kind && $this->module == 'admin') {
         $kind = 'admin';
     }
     // check REQUEST_METHOD in controller
     if ($type == 'controller') {
         $allowedMethod = $xml_info->action->{$this->act}->method;
         if (!$allowedMethod) {
             $allowedMethodList[0] = 'POST';
         } else {
             $allowedMethodList = explode('|', strtoupper($allowedMethod));
         }
         if (!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList)) {
             $this->error = "msg_invalid_request";
             $oMessageObject = self::getModuleInstance('message', $display_mode);
             $oMessageObject->setError(-1);
             $oMessageObject->setMessage($this->error);
             $oMessageObject->dispMessage();
             return $oMessageObject;
         }
     }
     // check CSRF for non-GET (POST, PUT, etc.) actions
     if (Context::getRequestMethod() !== 'GET' && Context::isInstalled()) {
         if ($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF()) {
             $this->_setInputErrorToContext();
             $this->error = 'msg_invalid_request';
             $oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
             $oMessageObject->setError(-1);
             $oMessageObject->setMessage($this->error);
             $oMessageObject->dispMessage();
             return $oMessageObject;
         }
     }
     if ($this->module_info->use_mobile != "Y") {
         Mobile::setMobile(FALSE);
     }
     $logged_info = Context::get('logged_info');
     // if(type == view, and case for using mobilephone)
     if ($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled()) {
         $orig_type = "view";
         $type = "mobile";
         // create a module instance
         $oModule = self::getModuleInstance($this->module, $type, $kind);
         if (!is_object($oModule) || !method_exists($oModule, $this->act)) {
             $type = $orig_type;
             Mobile::setMobile(FALSE);
             $oModule = self::getModuleInstance($this->module, $type, $kind);
         }
     } else {
         // create a module instance
         $oModule = self::getModuleInstance($this->module, $type, $kind);
     }
     if (!is_object($oModule)) {
         self::_setInputErrorToContext();
         $oMessageObject = self::getModuleInstance('message', $display_mode);
         $oMessageObject->setError(-1);
         $oMessageObject->setMessage($this->error);
         $oMessageObject->dispMessage();
         if ($this->httpStatusCode) {
             $oMessageObject->setHttpStatusCode($this->httpStatusCode);
         }
         return $oMessageObject;
     }
     // If there is no such action in the module object
     if (!isset($xml_info->action->{$this->act}) || !method_exists($oModule, $this->act)) {
         if (!Context::isInstalled()) {
             self::_setInputErrorToContext();
             $this->error = 'msg_invalid_request';
             $oMessageObject = self::getModuleInstance('message', $display_mode);
             $oMessageObject->setError(-1);
             $oMessageObject->setMessage($this->error);
             $oMessageObject->dispMessage();
             if ($this->httpStatusCode) {
                 $oMessageObject->setHttpStatusCode($this->httpStatusCode);
             }
             return $oMessageObject;
         }
         $forward = NULL;
         // 1. Look for the module with action name
         if (preg_match('/^([a-z]+)([A-Z])([a-z0-9\\_]+)(.*)$/', $this->act, $matches)) {
             $module = strtolower($matches[2] . $matches[3]);
             $xml_info = $oModuleModel->getModuleActionXml($module);
             if ($xml_info->action->{$this->act} && (stripos($this->act, 'admin') !== FALSE || $xml_info->action->{$this->act}->standalone != 'false')) {
                 $forward = new stdClass();
                 $forward->module = $module;
                 $forward->type = $xml_info->action->{$this->act}->type;
                 $forward->ruleset = $xml_info->action->{$this->act}->ruleset;
                 $forward->act = $this->act;
             } else {
                 $this->error = 'msg_invalid_request';
                 $oMessageObject = self::getModuleInstance('message', $display_mode);
                 $oMessageObject->setError(-1);
                 $oMessageObject->setMessage($this->error);
                 $oMessageObject->dispMessage();
                 return $oMessageObject;
             }
         }
         if (!$forward) {
             $forward = $oModuleModel->getActionForward($this->act);
         }
         if ($forward->module && $forward->type && $forward->act && $forward->act == $this->act) {
             $kind = stripos($forward->act, 'admin') !== FALSE ? 'admin' : '';
             $type = $forward->type;
             $ruleset = $forward->ruleset;
             $tpl_path = $oModule->getTemplatePath();
             $orig_module = $oModule;
             $xml_info = $oModuleModel->getModuleActionXml($forward->module);
             // SECISSUE also check foward act method
             // check REQUEST_METHOD in controller
             if ($type == 'controller') {
                 $allowedMethod = $xml_info->action->{$forward->act}->method;
                 if (!$allowedMethod) {
                     $allowedMethodList[0] = 'POST';
                 } else {
                     $allowedMethodList = explode('|', strtoupper($allowedMethod));
                 }
                 if (!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList)) {
                     $this->error = "msg_invalid_request";
                     $oMessageObject = self::getModuleInstance('message', $display_mode);
                     $oMessageObject->setError(-1);
                     $oMessageObject->setMessage($this->error);
                     $oMessageObject->dispMessage();
                     return $oMessageObject;
                 }
             }
             // check CSRF for non-GET (POST, PUT, etc.) actions
             if (Context::getRequestMethod() !== 'GET' && Context::isInstalled()) {
                 if ($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF()) {
                     $this->_setInputErrorToContext();
                     $this->error = 'msg_invalid_request';
                     $oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
                     $oMessageObject->setError(-1);
                     $oMessageObject->setMessage($this->error);
                     $oMessageObject->dispMessage();
                     return $oMessageObject;
                 }
             }
             if ($type == "view" && Mobile::isFromMobilePhone()) {
                 $orig_type = "view";
                 $type = "mobile";
                 // create a module instance
                 $oModule = self::getModuleInstance($forward->module, $type, $kind);
                 if (!is_object($oModule) || !method_exists($oModule, $this->act)) {
                     $type = $orig_type;
                     Mobile::setMobile(FALSE);
                     $oModule = self::getModuleInstance($forward->module, $type, $kind);
                 }
             } else {
                 $oModule = self::getModuleInstance($forward->module, $type, $kind);
             }
             if (!is_object($oModule)) {
                 self::_setInputErrorToContext();
                 $oMessageObject = self::getModuleInstance('message', $display_mode);
                 $oMessageObject->setError(-1);
                 $oMessageObject->setMessage('msg_module_is_not_exists');
                 $oMessageObject->dispMessage();
                 if ($this->httpStatusCode) {
                     $oMessageObject->setHttpStatusCode($this->httpStatusCode);
                 }
                 return $oMessageObject;
             }
             if ($this->module == "admin" && $type == "view") {
                 if ($logged_info->is_admin == 'Y') {
                     if ($this->act != 'dispLayoutAdminLayoutModify') {
                         $oAdminView = getAdminView('admin');
                         $oAdminView->makeGnbUrl($forward->module);
                         $oModule->setLayoutPath("./modules/admin/tpl");
                         $oModule->setLayoutFile("layout.html");
                     }
                 } else {
                     self::_setInputErrorToContext();
                     $this->error = 'admin.msg_is_not_administrator';
                     $oMessageObject = self::getModuleInstance('message', $display_mode);
                     $oMessageObject->setError(-1);
                     $oMessageObject->setMessage($this->error);
                     $oMessageObject->dispMessage();
                     return $oMessageObject;
                 }
             }
             if ($kind == 'admin') {
                 $grant = $oModuleModel->getGrant($this->module_info, $logged_info);
                 if (!$grant->manager) {
                     self::_setInputErrorToContext();
                     $this->error = 'admin.msg_is_not_administrator';
                     $oMessageObject = self::getModuleInstance('message', $display_mode);
                     $oMessageObject->setError(-1);
                     $oMessageObject->setMessage($this->error);
                     $oMessageObject->dispMessage();
                     return $oMessageObject;
                 } else {
                     if (!$grant->is_admin && $this->module != $this->orig_module->module && $xml_info->permission->{$this->act} != 'manager') {
                         self::_setInputErrorToContext();
                         $this->error = 'admin.msg_is_not_administrator';
                         $oMessageObject = self::getModuleInstance('message', $display_mode);
                         $oMessageObject->setError(-1);
                         $oMessageObject->setMessage($this->error);
                         $oMessageObject->dispMessage();
                         return $oMessageObject;
                     }
                 }
             }
         } else {
             if ($xml_info->default_index_act && method_exists($oModule, $xml_info->default_index_act)) {
                 $this->act = $xml_info->default_index_act;
             } else {
                 $this->error = 'msg_invalid_request';
                 $oModule->setError(-1);
                 $oModule->setMessage($this->error);
                 return $oModule;
             }
         }
     }
     // ruleset check...
     if (!empty($ruleset)) {
         $rulesetModule = $forward->module ? $forward->module : $this->module;
         $rulesetFile = $oModuleModel->getValidatorFilePath($rulesetModule, $ruleset, $this->mid);
         if (!empty($rulesetFile)) {
             if ($_SESSION['XE_VALIDATOR_ERROR_LANG']) {
                 $errorLang = $_SESSION['XE_VALIDATOR_ERROR_LANG'];
                 foreach ($errorLang as $key => $val) {
                     Context::setLang($key, $val);
                 }
                 unset($_SESSION['XE_VALIDATOR_ERROR_LANG']);
             }
             $Validator = new Validator($rulesetFile);
             $result = $Validator->validate();
             if (!$result) {
                 $lastError = $Validator->getLastError();
                 $returnUrl = Context::get('error_return_url');
                 $errorMsg = $lastError['msg'] ? $lastError['msg'] : 'validation error';
                 //for xml response
                 $oModule->setError(-1);
                 $oModule->setMessage($errorMsg);
                 //for html redirect
                 $this->error = $errorMsg;
                 $_SESSION['XE_VALIDATOR_ERROR'] = -1;
                 $_SESSION['XE_VALIDATOR_MESSAGE'] = $this->error;
                 $_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = 'error';
                 $_SESSION['XE_VALIDATOR_RETURN_URL'] = $returnUrl;
                 $_SESSION['XE_VALIDATOR_ID'] = Context::get('xe_validator_id');
                 self::_setInputValueToSession();
                 return $oModule;
             }
         }
     }
     $oModule->setAct($this->act);
     $this->module_info->module_type = $type;
     $oModule->setModuleInfo($this->module_info, $xml_info);
     $skipAct = array('dispEditorConfigPreview' => 1, 'dispLayoutPreviewWithModule' => 1);
     $db_use_mobile = Mobile::isMobileEnabled();
     $tablet_use = Rhymix\Framework\UA::isTablet();
     $config_tablet_use = config('mobile.tablets');
     if ($type == "view" && $this->module_info->use_mobile == "Y" && Mobile::isMobileCheckByAgent() && !isset($skipAct[Context::get('act')]) && $db_use_mobile === true && ($tablet_use === true && $config_tablet_use === false) === false) {
         global $lang;
         $header = '<style>div.xe_mobile{opacity:0.7;margin:1em 0;padding:.5em;background:#333;border:1px solid #666;border-left:0;border-right:0}p.xe_mobile{text-align:center;margin:1em 0}a.xe_mobile{color:#ff0;font-weight:bold;font-size:24px}@media only screen and (min-width:500px){a.xe_mobile{font-size:15px}}</style>';
         $footer = '<div class="xe_mobile"><p class="xe_mobile"><a class="xe_mobile" href="' . getUrl('m', '1') . '">' . $lang->msg_pc_to_mobile . '</a></p></div>';
         Context::addHtmlHeader($header);
         Context::addHtmlFooter($footer);
     }
     if ($type == "view" && $kind != 'admin') {
         $module_config = $oModuleModel->getModuleConfig('module');
         if ($module_config->htmlFooter) {
             Context::addHtmlFooter($module_config->htmlFooter);
         }
         if ($module_config->siteTitle) {
             if (!Context::getBrowserTitle()) {
                 Context::setBrowserTitle($module_config->siteTitle);
             }
         }
     }
     // if failed message exists in session, set context
     self::_setInputErrorToContext();
     $procResult = $oModule->proc();
     $methodList = array('XMLRPC' => 1, 'JSON' => 1, 'JS_CALLBACK' => 1);
     if (!$oModule->stop_proc && !isset($methodList[Context::getRequestMethod()])) {
         $error = $oModule->getError();
         $message = $oModule->getMessage();
         $messageType = $oModule->getMessageType();
         $redirectUrl = $oModule->getRedirectUrl();
         if (!$procResult) {
             $this->error = $message;
             if (!$redirectUrl && Context::get('error_return_url')) {
                 $redirectUrl = Context::get('error_return_url');
             }
             self::_setInputValueToSession();
         }
         if ($error != 0) {
             $_SESSION['XE_VALIDATOR_ERROR'] = $error;
         }
         if ($validator_id = Context::get('xe_validator_id')) {
             $_SESSION['XE_VALIDATOR_ID'] = $validator_id;
         }
         if ($message != 'success') {
             $_SESSION['XE_VALIDATOR_MESSAGE'] = $message;
             $_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = $messageType;
         }
         if (Context::get('xeVirtualRequestMethod') != 'xml' && $redirectUrl) {
             $_SESSION['XE_VALIDATOR_RETURN_URL'] = $redirectUrl;
         }
     }
     unset($logged_info);
     return $oModule;
 }