"._COM_SEF_CHK_PERMS); if (is_readable($sef_config_class)) require_once($sef_config_class); else die(_COM_SEF_NOREAD."( $sef_config_class )
"._COM_SEF_CHK_PERMS); // V 1.3.1 allow internal redirect for outbound links $shtask = mosGetParam($_GET,'shtask'); $shtarget = mosGetParam($_GET, 'shtarget'); if ($shtask == 'redirect' && !empty($shtarget)) { shRedirect($shtarget, '', '303'); } // V 1.2.4.t include language file shIncludeLanguageFile(); $sefConfig = new SEFConfig(); _log(str_repeat('-', 69)); _log('New request : '.(empty($_SERVER['REQUEST_URI']) ? '': $_SERVER['REQUEST_URI'])); _log(str_repeat('-', 69)); _log("\n".'$_SERVER', $_SERVER); // do security checks shDoSecurityChecks(); shCleanUpSecLogFiles(); // we don't really want to do this at each page load if ($sefConfig->Enabled) { $sef404 = sh404SEF_FRONT_ABS_PATH.'sef404.php'; if (is_readable($sef404)) { global $sefConfig; // V 1.2.4.r special processing for SEF without mod_rewrite $shSaveRequestURI = $_SERVER['REQUEST_URI']; // V x // V 1.2.4.j 2007-04-16 use own config secure url to fix ssl switch management // V 1.2.4.t moved here from sef404.php $http_host = explode(':', $_SERVER['HTTP_HOST'] ); if( (!empty( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) != 'off' || isset( $http_host[1] ) && $http_host[1] == 443)) { $shTemp = str_replace( 'http://', '', $GLOBALS['mosConfig_live_site']); $shTemp = str_replace( 'https://', '', $shTemp); // some sites may be running https ! $shHttpsSave = empty( $sefConfig->shConfig_live_secure_site) ? 'https://'. $shTemp : $sefConfig->shConfig_live_secure_site; _log('Request in SSL mode'.$shHttpsSave); } else $shHttpsSave = null; if (!empty($shHttpsSave)) $GLOBALS['mosConfig_live_site'] = $shHttpsSave; if (!empty($sefConfig->shRewriteMode) && strpos( $_SERVER['REQUEST_URI'], $sefConfig->shRewriteStrings[$sefConfig->shRewriteMode]) !== false ) { $bits = explode($sefConfig->shRewriteStrings[$sefConfig->shRewriteMode], $_SERVER['REQUEST_URI']); $base = (isset($bits[0]) ? $bits[0] : '').'/'; $index = 'index.php'; $base = str_replace( '/'.$index, '', $base); if (isset($bits[1])) $_SERVER['REQUEST_URI'] = $base.$bits[1]; else $_SERVER['REQUEST_URI'] = $base; $_SERVER['PHP_SELF'] = $base.$index; } else { $index = str_replace($GLOBALS['mosConfig_live_site'],"",$_SERVER['PHP_SELF']); $base = dirname($index); if ($base =="\\") $base = "/"; $base .= (($base == "/") ? "" :"/"); $index = basename($index); } $URI = array(); if (isset ($_SERVER['REQUEST_URI'])) { //strip out the base $REQUEST = str_replace($GLOBALS['mosConfig_live_site'],'',$_SERVER['REQUEST_URI']); if (!empty($shHttpsSave)) $REQUEST = str_replace($shHttpsSave,'',$_SERVER['REQUEST_URI']); $REQUEST = preg_replace('/^'.preg_quote($base,'/').'/','',$REQUEST); // V 1.2.4. preserve ? / is it a good idea ? $URI = new sh_Net_URL((empty($shHttpsSave)?$GLOBALS['mosConfig_live_site']:$shHttpsSave).'/'.ltrim($REQUEST,'/')); }else{ $QUERY_STRING = isset($_SERVER['QUERY_STRING']) ? '?'.$_SERVER['QUERY_STRING'] : ''; $URI = new sh_Net_URL($index.$QUERY_STRING); } // V 1.2.4.s // TODO Redirect any host to $mosConfig_live_site - in case same site is accessed through synonyms domains if ($sefConfig->shAutoRedirectWww && empty($_POST)) { // mode = false do nothing, true = auto-redirect // Auto redirect will do a 301 from www to non-www if mosConfig_live_site does not have www // and from non-www to www if mosConfig_live_site has www $shTemp = explode('/', str_replace($URI->protocol.'://', '', $GLOBALS['mosConfig_live_site']) ); $shLiveSite = strtolower($shTemp[0]); if ($shLiveSite != strtolower($_SERVER['HTTP_HOST'].(!sh404SEF_USE_NON_STANDARD_PORT || empty($URI->port) ? '' : ':'.$URI->port))) { if (substr( $shLiveSite, 0, 4) == 'www.' && strtolower('www.'.$_SERVER['HTTP_HOST'].(!sh404SEF_USE_NON_STANDARD_PORT || empty($URI->port) ? '' : ':'.$URI->port)) == $shLiveSite) { _log('Redirecting from non www to wwww'); shRedirect( $URI->protocol.'://www.'.$_SERVER['HTTP_HOST'].(!sh404SEF_USE_NON_STANDARD_PORT || empty($URI->port) ? '' : ':'.$URI->port).$shSaveRequestURI); } if (substr( $shLiveSite, 0, 4) != 'www.' && strtolower(substr( $_SERVER['HTTP_HOST'].(!sh404SEF_USE_NON_STANDARD_PORT || empty($URI->port) ? '' : ':'.$URI->port), 4)) == $shLiveSite) { _log('Redirecting from www to non wwww'); shRedirect($URI->protocol.'://'.str_replace('www.', '', $_SERVER['HTTP_HOST'].(!sh404SEF_USE_NON_STANDARD_PORT || empty($URI->port) ? '' : ':'.$URI->port)).$shSaveRequestURI); } } } //Make sure host name matches our config, we need this later. if (strpos($GLOBALS['mosConfig_live_site'],$URI->host) === false) { _log('Redirecting to home : host don\'t match our config'); shRedirect($GLOBALS['mosConfig_live_site']); } else { $shCurrentPageURL = $URI->protocol.'://'.$URI->host.(!sh404SEF_USE_NON_STANDARD_PORT || empty($URI->port) ? '' : ':'.$URI->port).$URI->path; _log('Current page URL : '.$shCurrentPageURL); $shCurrentPagePath = str_replace( $GLOBALS['mosConfig_live_site'], '', $shCurrentPageURL); _log('Current page path : '.$shCurrentPagePath); // V 1.2.4.s PR2 : workaround for Virtuemart cookie check issue // see second part in sef404.php if (shIsSearchEngine()) { // simulate doing successfull cookie check _log('Setting VMCHECK cookie for search engine'); $_COOKIE['VMCHECK'] = 'OK'; $_REQUEST['vmcchk'] = 1; } include_once($sef404); } } else die(_COM_SEF_NOREAD."( $sef404 )
"._COM_SEF_CHK_PERMS); } else{ $mambo_sef = sh404SEF_ABS_PATH.'includes/sef.php'; if (is_readable($mambo_sef)) include($mambo_sef); else { die(_COM_SEF_NOREAD."( $mambo_sef )
"._COM_SEF_CHK_PERMS); } } } else{ function sefRelToAbs( $string ) { return $string; } } function shIsSearchEngine() { // return true if user agant is a search engine static $isSearchEngine = null; static $searchEnginesAgents = array( 'B-l-i-t-z-B-O-T' ,'Baiduspider' ,'BlitzBot' ,'btbot' ,'DiamondBot' ,'Exabot' ,'FAST Enterprise Crawler' ,'FAST-WebCrawler/' ,'g2Crawler' ,'genieBot' ,'Gigabot' ,'Girafabot' ,'Googlebot' ,'ia_archiver' ,'ichiro' ,'Mediapartners-Google' ,'Mnogosearch' ,'msnbot' ,'MSRBOT' ,'Nusearch Spider' ,'SearchSight' ,'Seekbot' ,'sogou spider' ,'Speedy Spider' ,'Ask Jeeves/Teoma' ,'VoilaBot' ,'Yahoo!' ,'Slurp' ,'YahooSeeker' ); //return true; if (!is_null ($isSearchEngine)) { return $isSearchEngine; } else { $isSearchEngine = false; $useragent = empty($_SERVER['HTTP_USER_AGENT']) ? '' : strtolower($_SERVER['HTTP_USER_AGENT']); if (!empty($useragent)) foreach ($searchEnginesAgents as $searchEnginesAgent) if (strpos($useragent, strtolower($searchEnginesAgent)) !== false ) { $isSearchEngine = true; return true; } return $isSearchEngine; } } // V x : performs various security checks before allowing to go any further function shDoSecurityChecks( $query = '', $fullCheck = true) { global $sefConfig; if (!$sefConfig->shSecEnableSecurity) return ''; $shQuery = empty($query) ? urldecode( $_SERVER['QUERY_STRING']) : urldecode($query) ; $shQuery = str_replace('&', '&', $shQuery); $ip = empty($_SERVER['REMOTE_ADDR']) ? '' : $_SERVER['REMOTE_ADDR']; $uAgent = empty($_SERVER['HTTP_USER_AGENT']) ? '' : $_SERVER['HTTP_USER_AGENT']; // ip White/Black listing $shWhiteListedIp = shCheckIPList($ip, $sefConfig->ipWhiteList); if (!$shWhiteListedIp) if (shCheckIPList($ip, $sefConfig->ipBlackList)) shDoRestrictedAccess('Blacklisted IP'); if (!$shWhiteListedIp && $fullCheck) shDoAntiFloodCheck($ip); // bad content in query string $c = shCheckConfigVars($shQuery); if ($c) shDoRestrictedAccess($c.' in URL'); $c = shCheckBase64($shQuery); if ($c) shDoRestrictedAccess($c.' in URL'); $c = shCheckScripts($shQuery); if ($c) shDoRestrictedAccess($c.' in URL'); $c = shCheckStandardVars($_GET); if ($c) shDoRestrictedAccess($c.' in URL'); $c = shCheckImgTxtCmd($shQuery); // V x if ($c) shDoRestrictedAccess($c.' in URL'); // UserAgent White/Black listing if (!shCheckUAgentList($uAgent, $sefConfig->uAgentWhiteList)) if (shCheckUAgentList($uAgent, $sefConfig->uAgentBlackList)) shDoRestrictedAccess('BlackListed user agent'); if (!$fullCheck) return; // don't check POST and/or Honey pot if second check // check POST variables if ($sefConfig->shSecCheckPOSTData) { foreach($_POST as $key=>$value) { $c = shCheckConfigVars($key.'='.$value); if ($c) shDoRestrictedAccess($c.' in POST'); $c = shCheckBase64($key.'='.$value); if ($c) shDoRestrictedAccess($c.' in POST'); $c = shCheckScripts($key.'='.$value); if ($c) shDoRestrictedAccess($c.' in POST'); $c = shCheckStandardVars($_POST); if ($c) shDoRestrictedAccess($c.' in POST'); $c = shCheckImgTxtCmd($key.'='.$value); // V x if ($c) shDoRestrictedAccess($c.' in POST'); } } // do Project Honey Pot check if (!$shWhiteListedIp && $sefConfig->shSecCheckHoneyPot) shDoHoneyPotCheck($ip); } function shSendEmailToAdmin($logData) { if (!sh404SEF_SEC_MAIL_ATTACKS_TO_ADMIN) return; global $mosConfig_sitename, $mosConfig_live_site, $mosConfig_mailfrom, $mosConfig_fromname; $subject = str_replace( '%sh404SEF_404_SITE_NAME%', $mosConfig_sitename, sh404SEF_SEC_EMAIL_TO_ADMIN_SUBJECT); $details = array( ' Date', "\n".' Time', "\n".' Cause', "\n".' IP', "\n".' Name', "\n".' User agent', "\n"."\n".' Request method', "\n".' Request URI', "\n".' Comment'); $items = explode("\t", $logData); $count = 0; $detailText = ''; foreach ($details as $detail) { $detailText .= $detail . ' :: ' . trim($items[$count++]); } $body = str_replace( '%sh404SEF_404_SITE_URL%',$mosConfig_live_site , sh404SEF_SEC_EMAIL_TO_ADMIN_BODY); $body = str_replace( '%sh404SEF_404_ATTACK_DETAILS%', $detailText, $body); if (!defined('_ISO')) define('_ISO', 'charset=iso-8859-1'); mosMail( $mosConfig_mailfrom, $mosConfig_fromname, $mosConfig_mailfrom, $subject, $body); } function shLogToSecFile($logData) { $shNum = 12*(intval(date('Y')) - 2000)+intval(date('m')); // number current month $shFileName = sh404SEF_ADMIN_ABS_PATH.'logs/'.date('Y').'-'.date('m').'-'.'sh404SEF_security_log.'.$shNum.'.txt'; $fileIsThere = file_exists($shFileName); if (!$fileIsThere) { // create file $fileHeader = "Date\tTime\tCause\tIP\tName\tUser agent\tRequest method\tRequest URI\tComment\n"; } else $fileHeader = ''; if (!$fileIsThere || ($fileIsThere && is_writable($shFileName))) { $logFile=fopen( $shFileName,'ab'); if ($logFile) { if (!empty($fileHeader)) fWrite( $logFile, $fileHeader); fWrite( $logFile, $logData); fClose( $logFile); } } } function shCleanUpSecLogFiles(){ // delete security log files older than param global $sefConfig; if (mt_rand(1, SH404SEF_PAGES_TO_CLEAN_LOGS) != 1) return; // probability = 1/SH404SEF_PAGES_TO_CLEAN_LOGS $curMonth = 12*(intval(date('Y')) - 2000)+intval(date('m')); if ($sefConfig->shSecLogAttacks) { if ($handle = opendir(sh404SEF_ADMIN_ABS_PATH.'logs/')) { while (false !== ($file = readdir($handle))) { $matches = array(); if ($file != '.' && $file != '..' &&preg_match('/\.[0-9]*\./', $file, $matches)) { $fileNum = trim($matches[0], '.'); if ($curMonth-$fileNum > $sefConfig->monthsToKeepLogs) { @unlink(sh404SEF_ADMIN_ABS_PATH.'logs/'.$file); _log('Erasing security log file : '.$file); } } } closedir($handle); } } } function shDoRestrictedAccess( $causeText, $comment = '', $displayEntrance = false) { global $sefConfig; if ($sefConfig->shSecLogAttacks) { // log what's happening $sep = "\t"; $logData = date('Y-m-d').$sep.date('H:i:s').$sep.$causeText.$sep.$_SERVER['REMOTE_ADDR'].$sep; $logData .= getHostByAddr( $_SERVER['REMOTE_ADDR']).$sep; $logData .= $_SERVER['HTTP_USER_AGENT'].$sep.$_SERVER['REQUEST_METHOD'].$sep.$_SERVER['REQUEST_URI'].$sep.$comment; $logData .="\n"; shLogToSecFile ($logData); } // V x : we can possibly send email to site admin, but not log shSendEmailToAdmin($logData); // actually restrict access if (!headers_sent()) { header('HTTP/1.0 403 FORBIDDEN'); } echo '

Forbidden access

'; if($displayEntrance) { ?> shSecEntranceText; ?> >>>>>>






shSecSmellyPotText; ?>>>

('.$causeText.')

'; } die(); } function shCheckConfigVars( $query) { if (empty($query)) return ''; if (preg_match( '/mosConfig_[a-zA-Z_]{1,21}=/i', $query)) return 'mosConfig_var'; else return ''; } function shCheckBase64( $query) { if (empty($query)) return ''; if (preg_match( '/base64_encode.*\(.*\)/i', $query)) return 'Base 64 encoded data'; else return ''; } function shCheckScripts( $query) { if (empty($query)) return ''; if (preg_match( '/(\<).*script.*(\>)/i', $query)) return '