{$val1['link']}
+-
+
- {$val2['link']}
+
-
+
- {$val3['link']} +
+
diff --git a/.htaccess b/.htaccess index 10da8e3b2..fe203659a 100644 --- a/.htaccess +++ b/.htaccess @@ -17,13 +17,10 @@ RewriteRule ^(.+)\.min\.(css|js)$ ./$1.$2 [L] # rss, blogAPI RewriteRule ^(rss|atom)$ ./index.php?module=rss&act=$1 [L] RewriteRule ^([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?mid=$1&act=$2 [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?vid=$1&mid=$2&act=$3 [L] # trackback RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L] RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?mid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&mid=$2&document_srl=$3&key=$4&act=trackback [L] # document category RewriteRule ^([a-zA-Z0-9_]+)/category/([0-9]+)$ ./index.php?mid=$1&category=$2 [L,QSA] @@ -39,15 +36,5 @@ RewriteRule ^([a-zA-Z0-9_]+)/?$ ./index.php?mid=$1 [L,QSA] # mid + document link RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L,QSA] -# vid + mid link -RewriteCond %{SCRIPT_FILENAME} !-d -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ ./index.php?vid=$1&mid=$2 [L,QSA] - -# vid + mid + document link -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L,QSA] - # mid + entry title RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L,QSA] - -# vid + mid + entry title -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?vid=$1&mid=$2&entry=$3 [L,QSA] diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index b4b5b3582..6cf37761c 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -238,7 +238,6 @@ class Context // Set global variables for backward compatibility. $GLOBALS['__Context__'] = $this; - $this->_COOKIE = $_COOKIE; // Set information about the current request. $this->setRequestMethod(); @@ -261,23 +260,26 @@ class Context { $oModuleModel = getModel('module'); $site_module_info = $oModuleModel->getDefaultMid() ?: new stdClass; - - // if site_srl of site_module_info is 0 (default site), compare the domain to default_url of db_config - if($site_module_info->site_srl == 0 && $site_module_info->domain != $this->db_info->default_url) - { - $site_module_info->domain = $this->db_info->default_url; - } - self::set('site_module_info', $site_module_info); - if($site_module_info->site_srl && isSiteID($site_module_info->domain)) - { - self::set('vid', $site_module_info->domain, TRUE); - } + self::set('_default_timezone', ($site_module_info->settings && $site_module_info->settings->timezone) ? $site_module_info->settings->timezone : null); + self::set('_default_url', self::$_instance->db_info->default_url = self::getDefaultUrl($site_module_info)); + self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null); + self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null); + self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none'); } else { $site_module_info = new stdClass; } + + // Redirect to SSL if the current domain always uses SSL. + if ($site_module_info->security === 'always' && !RX_SSL && PHP_SAPI !== 'cli' && !$site_module_info->is_default_replaced) + { + $ssl_url = self::getDefaultUrl($site_module_info) . RX_REQUEST_URL; + self::setCacheControl(0); + header('Location: ' . $ssl_url, true, 301); + exit; + } // Load language support. $enabled_langs = self::loadLangSelected(); @@ -311,9 +313,9 @@ class Context if(!$this->lang_type || !isset($enabled_langs[$this->lang_type])) { - if($site_module_info->default_language) + if($site_module_info->settings->language) { - $this->lang_type = $this->db_info->lang_type = $site_module_info->default_language; + $this->lang_type = $this->db_info->lang_type = $site_module_info->settings->language; } else { @@ -340,7 +342,9 @@ class Context // start session $relax_key_checks = ($this->act === 'procFileUpload' && preg_match('/shockwave\s?flash/i', $_SERVER['HTTP_USER_AGENT'])); + Rhymix\Framework\Session::checkSSO($site_module_info); Rhymix\Framework\Session::start(false, $relax_key_checks); + $this->_COOKIE = $_COOKIE; // start output buffer ob_start(); @@ -474,9 +478,6 @@ class Context // Copy to old format for backward compatibility. self::$_instance->db_info = self::convertDBInfo($config); self::$_instance->allow_rewrite = self::$_instance->db_info->use_rewrite === 'Y'; - self::set('_http_port', self::$_instance->db_info->http_port ?: null); - self::set('_https_port', self::$_instance->db_info->https_port ?: null); - self::set('_use_ssl', self::$_instance->db_info->use_ssl); $GLOBALS['_time_zone'] = self::$_instance->db_info->time_zone; } @@ -528,14 +529,6 @@ class Context $db_info->ftp_info->ftp_pasv = $config['ftp']['pasv'] ? 'Y' : 'N'; $db_info->ftp_info->ftp_root_path = $config['ftp']['path']; $db_info->ftp_info->sftp = $config['ftp']['sftp'] ? 'Y' : 'N'; - $db_info->default_url = $config['url']['default']; - if (!$db_info->default_url) - { - $db_info->default_url = (RX_SSL ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . RX_BASEURL; - } - $db_info->http_port = $config['url']['http_port']; - $db_info->https_port = $config['url']['https_port']; - $db_info->use_ssl = $config['url']['ssl']; $db_info->lang_type = $config['locale']['default_lang']; $db_info->time_zone = $config['locale']['internal_timezone']; $db_info->time_zone = sprintf('%s%02d%02d', $db_info->time_zone >= 0 ? '+' : '-', abs($db_info->time_zone) / 3600, (abs($db_info->time_zone) % 3600 / 60)); @@ -607,11 +600,26 @@ class Context /** * Return default URL * + * @param object $site_module_info (optional) * @return string Default URL */ - public static function getDefaultUrl() + public static function getDefaultUrl($site_module_info = null) { - return self::$_instance->db_info->default_url; + if ($site_module_info === null && ($default_url = self::get('_default_url'))) + { + return $default_url; + } + + if ($site_module_info === null) + { + $site_module_info === self::get('site_module_info'); + } + + $prefix = $site_module_info->security === 'always' ? 'https://' : 'http://'; + $hostname = $site_module_info->domain; + $port = $site_module_info->security === 'always' ? $site_module_info->https_port : $site_module_info->http_port; + $result = $prefix . $hostname . ($port ? sprintf(':%d', $port) : '') . RX_BASEURL; + return $result; } /** @@ -659,7 +667,7 @@ class Context */ public function checkSSO() { - return !Rhymix\Framework\Session::checkSSO(); + return true; } /** @@ -776,10 +784,10 @@ class Context */ public static function getSiteTitle() { - $moduleConfig = getModel('module')->getModuleConfig('module'); - if (isset($moduleConfig->siteTitle)) + $domain_info = self::get('site_module_info'); + if ($domain_info && $domain_info->settings && $domain_info->settings->title) { - $title = trim($moduleConfig->siteTitle); + $title = trim($domain_info->settings->title); getController('module')->replaceDefinedLangCode($title); return $title; } @@ -796,10 +804,10 @@ class Context */ public static function getSiteSubtitle() { - $moduleConfig = getModel('module')->getModuleConfig('module'); - if (isset($moduleConfig->siteSubtitle)) + $domain_info = self::get('site_module_info'); + if ($domain_info && $domain_info->settings && $domain_info->settings->subtitle) { - $subtitle = trim($moduleConfig->siteSubtitle); + $subtitle = trim($domain_info->settings->subtitle); getController('module')->replaceDefinedLangCode($subtitle); return $subtitle; } @@ -1540,76 +1548,59 @@ class Context */ public static function getUrl($num_args = 0, $args_list = array(), $domain = null, $encode = TRUE, $autoEncode = FALSE) { + static $current_domain = null; static $site_module_info = null; - static $current_info = null; - - // retrieve virtual site information - if(is_null($site_module_info)) + if ($site_module_info === null) { $site_module_info = self::get('site_module_info'); } - - // If $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid) - if($domain && isSiteID($domain)) + if ($current_domain === null) { - $vid = $domain; - $domain = ''; + $current_domain = parse_url(Rhymix\Framework\URL::getCurrentDomainURL(), PHP_URL_HOST); } - // If $domain, $vid are not set, use current site information - if(!$domain && !$vid) + // Find the canonical form of the domain. + if ($domain) { - if($site_module_info->domain && isSiteID($site_module_info->domain)) + if (strpos($domain, '/') !== false) { - $vid = $site_module_info->domain; + $domain = Rhymix\Framework\URL::getDomainFromURL($domain); } - else + if (strpos($domain, 'xn--') !== false) { - $domain = $site_module_info->domain; + $domain = Rhymix\Framework\URL::decodeIdna($domain); } } - - // if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain. - if($domain) + else { - $domain_info = parse_url($domain); - if(is_null($current_info)) - { - $current_info = parse_url((RX_SSL ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . RX_BASEURL); - } - if($domain_info['host'] . $domain_info['path'] == $current_info['host'] . $current_info['path']) - { - unset($domain); - } - else - { - $domain = rtrim(preg_replace('/^(http|https):\/\//i', '', trim($domain)), '/') . '/'; - } + $domain = $site_module_info->domain; } - $get_vars = array(); - - // If there is no GET variables or first argument is '' to reset variables - if(!self::$_instance->get_vars || $args_list[0] == '') + // If the domain is the same as the current domain, do not use it. + if ($domain && $domain === $current_domain) { - // rearrange args_list - if(is_array($args_list) && $args_list[0] == '') + $domain = null; + } + + // Get URL parameters. If the first argument is '', reset existing parameters. + if (!self::$_instance->get_vars || strval($args_list[0]) === '') + { + $get_vars = array(); + if(is_array($args_list) && strval($args_list[0]) === '') { array_shift($args_list); } } else { - // Otherwise, make GET variables into array $get_vars = get_object_vars(self::$_instance->get_vars); } - + // arrange args_list for($i = 0, $c = count($args_list); $i < $c; $i += 2) { $key = $args_list[$i]; $val = trim($args_list[$i + 1]); - // If value is not set, remove the key if(!isset($val) || !strlen($val)) { @@ -1619,18 +1610,11 @@ class Context // set new variables $get_vars[$key] = $val; } - + // remove vid, rnd unset($get_vars['rnd']); - if($vid) - { - $get_vars['vid'] = $vid; - } - else - { - unset($get_vars['vid']); - } - + unset($get_vars['vid']); + // for compatibility to lower versions $act = $get_vars['act']; $act_alias = array( @@ -1643,7 +1627,7 @@ class Context { $get_vars['act'] = $act_alias[$act]; } - + // organize URL $query = ''; if(count($get_vars) > 0) @@ -1653,47 +1637,32 @@ class Context { $var_keys = array_keys($get_vars); sort($var_keys); - $target = join('.', $var_keys); - $act = $get_vars['act']; - $vid = $get_vars['vid']; $mid = $get_vars['mid']; $key = $get_vars['key']; $srl = $get_vars['document_srl']; - $tmpArray = array('rss' => 1, 'atom' => 1, 'api' => 1); $is_feed = isset($tmpArray[$act]); - $target_map = array( - 'vid' => $vid, 'mid' => $mid, - 'mid.vid' => "$vid/$mid", 'category.mid' => "$mid/category/" . $get_vars['category'], 'entry.mid' => "$mid/entry/" . $get_vars['entry'], - 'entry.mid.vid' => "$vid/$mid/entry/" . $get_vars['entry'], 'document_srl' => $srl, 'document_srl.mid' => "$mid/$srl", - 'document_srl.vid' => "$vid/$srl", - 'document_srl.mid.vid' => "$vid/$mid/$srl", 'act' => ($is_feed && $act !== 'api') ? $act : '', 'act.mid' => $is_feed ? "$mid/$act" : '', - 'act.mid.vid' => $is_feed ? "$vid/$mid/$act" : '', 'act.document_srl.key' => ($act == 'trackback') ? "$srl/$key/$act" : '', 'act.document_srl.key.mid' => ($act == 'trackback') ? "$mid/$srl/$key/$act" : '', - 'act.document_srl.key.vid' => ($act == 'trackback') ? "$vid/$srl/$key/$act" : '', - 'act.document_srl.key.mid.vid' => ($act == 'trackback') ? "$vid/$mid/$srl/$key/$act" : '' ); - $query = $target_map[$target]; } - if(!$query && count($get_vars) > 0) { $query = 'index.php?' . http_build_query($get_vars); } } - + // If using SSL always $_use_ssl = self::get('_use_ssl'); if($_use_ssl == 'always') @@ -1759,7 +1728,7 @@ class Context */ public static function getRequestUri($ssl_mode = FOLLOW_REQUEST_SSL, $domain = null) { - static $url = array(); + static $domain_infos = array(); // Check HTTP Request if(!isset($_SERVER['SERVER_PROTOCOL'])) @@ -1772,20 +1741,6 @@ class Context $ssl_mode = ENFORCE_SSL; } - if($domain) - { - $domain_key = md5($domain); - } - else - { - $domain_key = 'default'; - } - - if(isset($url[$ssl_mode][$domain_key])) - { - return $url[$ssl_mode][$domain_key]; - } - switch($ssl_mode) { case FOLLOW_REQUEST_SSL: $use_ssl = RX_SSL; @@ -1796,50 +1751,21 @@ class Context break; } - if($domain) + $site_module_info = self::get('site_module_info'); + if ($domain !== null && $domain !== false && $domain !== $site_module_info->domain) { - $target_url = rtrim(trim($domain), '/') . '/'; - } - else - { - $target_url = $_SERVER['HTTP_HOST'] . RX_BASEURL; - } - - $url_info = parse_url('http://' . $target_url); - - if($use_ssl != RX_SSL) - { - unset($url_info['port']); - } - - if($use_ssl) - { - $port = self::get('_https_port'); - if($port && $port != 443) + if (!isset($domain_infos[$domain])) { - $url_info['port'] = $port; - } - elseif($url_info['port'] == 443) - { - unset($url_info['port']); + $domain_infos[$domain] = getModel('module')->getSiteInfoByDomain($domain); } + $site_module_info = $domain_infos[$domain] ?: $site_module_info; } - else - { - $port = self::get('_http_port'); - if($port && $port != 80) - { - $url_info['port'] = $port; - } - elseif($url_info['port'] == 80) - { - unset($url_info['port']); - } - } - - $url[$ssl_mode][$domain_key] = sprintf('%s://%s%s%s', $use_ssl ? 'https' : $url_info['scheme'], $url_info['host'], $url_info['port'] && $url_info['port'] != 80 ? ':' . $url_info['port'] : '', $url_info['path']); - - return $url[$ssl_mode][$domain_key]; + + $prefix = ($use_ssl && $site_module_info->security !== 'none') ? 'https://' : 'http://'; + $hostname = $site_module_info->domain; + $port = ($use_ssl && $site_module_info->security !== 'none') ? $site_module_info->https_port : $site_module_info->http_port; + $result = $prefix . $hostname . ($port ? sprintf(':%d', $port) : '') . RX_BASEURL; + return $result; } /** diff --git a/classes/display/HTMLDisplayHandler.php b/classes/display/HTMLDisplayHandler.php index aa67124a2..0e6360ace 100644 --- a/classes/display/HTMLDisplayHandler.php +++ b/classes/display/HTMLDisplayHandler.php @@ -221,9 +221,10 @@ class HTMLDisplayHandler } // set icon + $site_module_info = Context::get('site_module_info'); $oAdminModel = getAdminModel('admin'); - $favicon_url = $oAdminModel->getFaviconUrl(false); - $mobicon_url = $oAdminModel->getMobileIconUrl(false); + $favicon_url = $oAdminModel->getFaviconUrl($site_module_info->domain_srl); + $mobicon_url = $oAdminModel->getMobileIconUrl($site_module_info->domain_srl); Context::set('favicon_url', $favicon_url); Context::set('mobicon_url', $mobicon_url); @@ -500,7 +501,7 @@ class HTMLDisplayHandler Context::addOpenGraphData('og:image:width', $first_image['width']); Context::addOpenGraphData('og:image:height', $first_image['height']); } - elseif ($default_image = getAdminModel('admin')->getSiteDefaultImageUrl($width, $height)) + elseif ($default_image = getAdminModel('admin')->getSiteDefaultImageUrl($site_module_info->domain_srl, $width, $height)) { Context::addOpenGraphData('og:image', Rhymix\Framework\URL::getCurrentDomainURL($default_image)); if ($width && $height) diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index 983892843..e0eec9d44 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -126,6 +126,34 @@ class ModuleHandler extends Handler { $oModuleModel = getModel('module'); $site_module_info = Context::get('site_module_info'); + + // Check unregistered domain action. + if (!$site_module_info || !isset($site_module_info->domain_srl) || $site_module_info->is_default_replaced) + { + $site_module_info = getModel('module')->getDefaultDomainInfo(); + if ($site_module_info) + { + $domain_action = config('url.unregistered_domain_action') ?: 'redirect_301'; + switch ($domain_action) + { + case 'redirect_301': + header('Location: ' . Context::getDefaultUrl($site_module_info) . RX_REQUEST_URL, true, 301); + return false; + + case 'redirect_302': + header('Location: ' . Context::getDefaultUrl($site_module_info) . RX_REQUEST_URL, true, 302); + return false; + + case 'block': + $this->error = 'The site does not exist'; + $this->httpStatusCode = 404; + return true; + + case 'display': + // pass + } + } + } // if success_return_url and error_return_url is incorrect $urls = array(Context::get('success_return_url'), Context::get('error_return_url')); @@ -155,6 +183,7 @@ class ModuleHandler extends Handler } } + // Convert document alias (entry) to document_srl if(!$this->document_srl && $this->mid && $this->entry) { $oDocumentModel = getModel('document'); @@ -231,15 +260,6 @@ class ModuleHandler extends Handler //if($this->module && $module_info->module != $this->module) unset($module_info); } - // redirect, if module_site_srl and site_srl are different - if(!$this->module && !$module_info && $site_module_info->site_srl == 0 && $site_module_info->module_site_srl > 0) - { - Context::setCacheControl(0); - $site_info = $oModuleModel->getSiteInfo($site_module_info->module_site_srl); - header('location: ' . getNotEncodedSiteUrl($site_info->domain, 'mid', $site_module_info->mid), true, 301); - return false; - } - // If module_info is not set still, and $module does not exist, find the default module if(!$module_info && !$this->module && !$this->mid) { @@ -251,28 +271,14 @@ class ModuleHandler extends Handler $module_info = $site_module_info; } - // redirect, if site_srl of module_info is different from one of site's module_info - if($module_info && $module_info->site_srl != $site_module_info->site_srl && !Rhymix\Framework\UA::isRobot()) + // Set index document + if($site_module_info->index_document_srl && !$this->module && !$this->mid && !$this->document_srl && Context::getRequestMethod() === 'GET' && !count($_GET)) { - // If the module is of virtual site - if($module_info->site_srl) - { - $site_info = $oModuleModel->getSiteInfo($module_info->site_srl); - $redirect_url = getNotEncodedSiteUrl($site_info->domain, 'mid', Context::get('mid'), 'document_srl', Context::get('document_srl'), 'module_srl', Context::get('module_srl'), 'entry', Context::get('entry')); - // If it's called from a virtual site, though it's not a module of the virtual site - } - else - { - $redirect_url = getNotEncodedSiteUrl(Context::getDefaultUrl(), 'mid', Context::get('mid'), 'document_srl', Context::get('document_srl'), 'module_srl', Context::get('module_srl'), 'entry', Context::get('entry')); - } - - Context::setCacheControl(0); - header("Location: $redirect_url", true, 301); - return false; + Context::set('document_srl', $this->document_srl = $site_module_info->index_document_srl, true); } - + // redirect, if site start module - if(Context::getRequestMethod() === 'GET' && isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1) + if(!$site_module_info->index_document_srl && Context::getRequestMethod() === 'GET' && isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1) { Context::setCacheControl(0); header('location: ' . getNotEncodedSiteUrl($site_module_info->domain), true, 301); @@ -794,16 +800,16 @@ class ModuleHandler extends Handler if($type == "view" && $kind != 'admin') { - $module_config = $oModuleModel->getModuleConfig('module'); - if($module_config->htmlFooter) + $domain_info = Context::get('site_module_info'); + if ($domain_info && $domain_info->settings && $domain_info->settings->html_footer) { - Context::addHtmlFooter($module_config->htmlFooter); + Context::addHtmlFooter($domain_info->settings->html_footer); } - if($module_config->siteTitle) + if ($domain_info && $domain_info->settings && $domain_info->settings->title) { if(!Context::getBrowserTitle()) { - Context::setBrowserTitle($module_config->siteTitle); + Context::setBrowserTitle($domain_info->settings->title); } } } diff --git a/common/constants.php b/common/constants.php index 58e698e6b..16dad16b1 100644 --- a/common/constants.php +++ b/common/constants.php @@ -3,7 +3,7 @@ /** * RX_VERSION is the version number of the Rhymix CMS. */ -define('RX_VERSION', '1.8.33'); +define('RX_VERSION', '1.8.34'); /** * RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch. diff --git a/common/defaults/blacklist.php b/common/defaults/blacklist.php index b3add3eaf..a234750bf 100644 --- a/common/defaults/blacklist.php +++ b/common/defaults/blacklist.php @@ -10,7 +10,9 @@ return array( 'auto_login' => true, 'errorlogger' => true, 'fix_mysql_utf8' => true, + 'homepage' => true, 'member_communication' => true, + 'multidomain' => true, 'seo' => true, 'session_shield' => true, 'smartphone' => true, diff --git a/common/defaults/config.php b/common/defaults/config.php index 684824a7b..8a9f620ef 100644 --- a/common/defaults/config.php +++ b/common/defaults/config.php @@ -44,6 +44,7 @@ return array( ), 'url' => array( 'default' => null, + 'unregistered_domain_action' => 'redirect_301', 'http_port' => null, 'https_port' => null, 'ssl' => 'none', diff --git a/common/framework/datetime.php b/common/framework/datetime.php index 66511d2ba..c4df3a7ea 100644 --- a/common/framework/datetime.php +++ b/common/framework/datetime.php @@ -66,6 +66,10 @@ class DateTime { return $_SESSION['RHYMIX']['timezone']; } + elseif ($default = \Context::get('_default_timezone')) + { + return $default; + } elseif ($default = Config::get('locale.default_timezone')) { return $default; diff --git a/common/framework/session.php b/common/framework/session.php index 8ef115376..33c44bd9f 100644 --- a/common/framework/session.php +++ b/common/framework/session.php @@ -270,87 +270,92 @@ class Session * This method uses more or less the same logic as XE's SSO mechanism. * It may need to be changed to a more secure mechanism later. * - * @return bool + * @param object $site_module_info + * @return void */ - public static function checkSSO() + public static function checkSSO($site_module_info) { // Abort if SSO is disabled, the visitor is a robot, or this is not a typical GET request. if ($_SERVER['REQUEST_METHOD'] !== 'GET' || !config('use_sso') || UA::isRobot() || in_array(\Context::get('act'), array('rss', 'atom'))) { - return false; - } - - // Abort of the default URL is not set. - $default_url = \Context::getDefaultUrl(); - if (!$default_url) - { - return false; + return; } // Get the current site information. - $current_url = URL::getCurrentURL(); - $current_host = parse_url($current_url, \PHP_URL_HOST); - $default_host = parse_url($default_url, \PHP_URL_HOST); + $is_default_domain = ($site_module_info->domain_srl == 0); + if (!$is_default_domain) + { + $current_domain = $site_module_info->domain; + $current_url = URL::getCurrentUrl(); + $default_domain = getModel('module')->getDefaultDomainInfo(); + $default_url = \Context::getDefaultUrl($default_domain); + } // Step 1: if the current site is not the default site, send SSO validation request to the default site. - if($default_host !== $current_host && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_host)) + if(!$is_default_domain && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_domain)) { // Set sso cookie to prevent multiple simultaneous SSO validation requests. - setcookie('sso', md5($current_host), 0, '/'); + setcookie('sso', md5($current_domain), 0, '/'); // Redirect to the default site. $sso_request = Security::encrypt($current_url); header('Location:' . URL::modifyURL($default_url, array('sso_request' => $sso_request))); - return true; + exit; } // Step 2: receive and process SSO validation request at the default site. - if($default_host === $current_host && \Context::get('sso_request')) + if($is_default_domain && \Context::get('sso_request')) { // Get the URL of the origin site $sso_request = Security::decrypt(\Context::get('sso_request')); if (!$sso_request || !preg_match('!^https?://!', $sso_request)) { \Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); - return true; + exit; + } + if (!URL::isInternalUrl($sso_request) || !Security::checkCSRF()) + { + \Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); + exit; } - // Redirect back to the origin site. + // Encrypt the session ID. + self::start(true); $sso_response = Security::encrypt(session_id()); + + // Redirect back to the origin site. header('Location: ' . URL::modifyURL($sso_request, array('sso_response' => $sso_response))); - return true; + self::close(); + exit; } // Step 3: back at the origin site, set session ID to be the same as the default site. - if($default_host !== $current_host && \Context::get('sso_response')) + if(!$is_default_domain && \Context::get('sso_response')) { // Check SSO response $sso_response = Security::decrypt(\Context::get('sso_response')); if ($sso_response === false) { \Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); - return true; + exit; } // 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) + if(isset($_SERVER['HTTP_REFERER']) && strpos(URL::decodeIdna($_SERVER['HTTP_REFERER']), $default_url) !== 0) { \Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); - return true; + exit; } - // Set session ID. - self::close(); + // Set the session ID. session_id($sso_response); - self::start(); + self::start(true, false); // Finally, redirect to the originally requested URL. header('Location: ' . URL::getCurrentURL(array('sso_response' => null))); - return true; + self::close(); + exit; } - - // If none of the conditions above apply, proceed normally. - return false; } /** diff --git a/common/framework/storage.php b/common/framework/storage.php index 86bcadffc..a9ff297be 100644 --- a/common/framework/storage.php +++ b/common/framework/storage.php @@ -456,6 +456,11 @@ class Storage return false; } + if (is_uploaded_file($source)) + { + @chmod($destination, 0666 & ~self::getUmask()); + } + if (function_exists('opcache_invalidate')) { if (substr($source, -4) === '.php') diff --git a/common/framework/url.php b/common/framework/url.php index f41c5dc09..05775cee5 100644 --- a/common/framework/url.php +++ b/common/framework/url.php @@ -98,7 +98,7 @@ class URL return true; } - if ($domain === self::getDomainFromURL(\Context::getDefaultUrl())) + if (getModel('module')->getSiteInfoByDomain($domain)) { return true; } diff --git a/common/legacy.php b/common/legacy.php index a976c5a6f..f41ef8d9d 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -1051,24 +1051,7 @@ function requirePear() */ function checkCSRF() { - // Use Rhymix Security class first. - if (Rhymix\Framework\Security::checkCSRF()) - { - return true; - } - - // Check if we have a virtual site with a matching domain. - $oModuleModel = getModel('module'); - $siteModuleInfo = $oModuleModel->getDefaultMid(); - $virtualSiteInfo = $oModuleModel->getSiteInfo($siteModuleInfo->site_srl); - if (strcasecmp($virtualSiteInfo->domain, Context::get('vid')) && stristr($virtualSiteInfo->domain, $referer_host)) - { - return true; - } - else - { - return false; - } + return Rhymix\Framework\Security::checkCSRF(); } /** diff --git a/common/manual/server_config/rhymix-nginx-subdir.conf b/common/manual/server_config/rhymix-nginx-subdir.conf index 3559ccb9c..3524fa495 100644 --- a/common/manual/server_config/rhymix-nginx-subdir.conf +++ b/common/manual/server_config/rhymix-nginx-subdir.conf @@ -31,11 +31,10 @@ location ~ ^/rhymix/(.+)\.min\.(css|js)$ { # rss, blogAPI rewrite ^/rhymix/(rss|atom)$ /rhymix/index.php?module=rss&act=$1 last; rewrite ^/rhymix/([a-zA-Z0-9_]+)/(rss|atom|api)$ /rhymix/index.php?mid=$1&act=$2 last; -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ /rhymix/index.php?vid=$1&mid=$2&act=$3 last; # trackback rewrite ^/rhymix/([0-9]+)/(.+)/trackback$ /rhymix/index.php?document_srl=$1&key=$2&act=trackback last; -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /rhymix/index.php?vid=$1&document_srl=$2&key=$3&act=trackback last; +rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /rhymix/index.php?mid=$1&document_srl=$2&key=$3&act=trackback last; # administrator page rewrite ^/rhymix/admin/?$ /rhymix/index.php?module=admin last; @@ -52,14 +51,5 @@ rewrite ^/rhymix/([a-zA-Z0-9_]+)/?$ /rhymix/index.php?mid=$1 last; # mid + document link rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?mid=$1&document_srl=$2 last; -# vid + mid link -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ /rhymix/index.php?vid=$1&mid=$2 last; - -# vid + mid + document link -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?vid=$1&mid=$2&document_srl=$3 last; - # mid + entry title rewrite ^/rhymix/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?mid=$1&entry=$2 last; - -# vid + mid + entry title -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?vid=$1&mid=$2&entry=$3 last; diff --git a/common/manual/server_config/rhymix-nginx.conf b/common/manual/server_config/rhymix-nginx.conf index 5ea8ab1e0..6edcf6922 100644 --- a/common/manual/server_config/rhymix-nginx.conf +++ b/common/manual/server_config/rhymix-nginx.conf @@ -31,11 +31,10 @@ location ~ ^/(.+)\.min\.(css|js)$ { # rss, blogAPI rewrite ^/(rss|atom)$ /index.php?module=rss&act=$1 last; rewrite ^/([a-zA-Z0-9_]+)/(rss|atom|api)$ /index.php?mid=$1&act=$2 last; -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ /index.php?vid=$1&mid=$2&act=$3 last; # trackback rewrite ^/([0-9]+)/(.+)/trackback$ /index.php?document_srl=$1&key=$2&act=trackback last; -rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /index.php?vid=$1&document_srl=$2&key=$3&act=trackback last; +rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /index.php?mid=$1&document_srl=$2&key=$3&act=trackback last; # administrator page rewrite ^/admin/?$ /index.php?module=admin last; @@ -52,14 +51,5 @@ rewrite ^/([a-zA-Z0-9_]+)/?$ /index.php?mid=$1 last; # mid + document link rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?mid=$1&document_srl=$2 last; -# vid + mid link -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ /index.php?vid=$1&mid=$2 last; - -# vid + mid + document link -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?vid=$1&mid=$2&document_srl=$3 last; - # mid + entry title rewrite ^/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?mid=$1&entry=$2 last; - -# vid + mid + entry title -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?vid=$1&mid=$2&entry=$3 last; diff --git a/common/tpl/common_layout.html b/common/tpl/common_layout.html index 4d12ec47a..3104e3c23 100644 --- a/common/tpl/common_layout.html +++ b/common/tpl/common_layout.html @@ -57,7 +57,7 @@ var https_port = {Context::get("_https_port") ?: 'null'}; var enforce_ssl = {Context::get('_use_ssl') === 'always' ? 'true' : 'false'}; var ssl_actions = {json_encode(array_keys(Context::getSSLActions()))}; - var xeVid = {json_encode($vid ?: null)}; + var xeVid = null; diff --git a/index.php b/index.php index bd0e2d53b..27aaa6a15 100644 --- a/index.php +++ b/index.php @@ -47,17 +47,10 @@ $oContext = Context::getInstance(); $oContext->init(); /** - * @brief If default_url is set and it is different from the current url, attempt to redirect for SSO authentication and then process the module + * @brief Initialize and execute Module Handler **/ -if($oContext->checkSSO()) -{ - $oModuleHandler = new ModuleHandler(); - - if($oModuleHandler->init()) - { - $oModuleHandler->displayContent($oModuleHandler->procModule()); - } -} +$oModuleHandler = new ModuleHandler(); +$oModuleHandler->init() && $oModuleHandler->displayContent($oModuleHandler->procModule()); Context::close(); diff --git a/layouts/simple_world/conf/info.xml b/layouts/simple_world/conf/info.xml index 04948cb54..507325cf4 100644 --- a/layouts/simple_world/conf/info.xml +++ b/layouts/simple_world/conf/info.xml @@ -4,8 +4,8 @@
{$lang->about_member_profile_view}
+