PageRenderTime 10ms CodeModel.GetById 2ms app.highlight 68ms RepoModel.GetById 1ms app.codeStats 0ms

/xoops_trust_path/modules/protector/class/protector.php

https://github.com/nouphet/momoxo
PHP | 1123 lines | 823 code | 194 blank | 106 comment | 246 complexity | 16a861c1dcf521e846fe02afe2bcc8a0 MD5 | raw file
   1<?php
   2
   3class Protector {
   4
   5var $mydirname ;
   6
   7var $_conn = null ;
   8var $_conf = array() ;
   9var $_conf_serialized = '' ;
  10
  11var $_bad_globals = array() ;
  12
  13var $message = '' ;
  14var $warning = false ;
  15var $error = false ;
  16var $_doubtful_requests = array() ;
  17var $_bigumbrella_doubtfuls = array() ;
  18
  19var $_dblayertrap_doubtfuls = array() ;
  20var $_dblayertrap_doubtful_needles = array(
  21	'information_schema' ,
  22	'select' ,
  23	"'" ,
  24	'"' ,
  25) ;
  26
  27var $_logged = false ;
  28
  29var $_done_badext = false ;
  30var $_done_intval = false ;
  31var $_done_dotdot = false ;
  32var $_done_nullbyte = false ;
  33var $_done_contami = false ;
  34var $_done_isocom = false ;
  35var $_done_union = false ;
  36var $_done_dos = false ;
  37
  38var $_safe_badext = true ;
  39var $_safe_contami = true ;
  40var $_safe_isocom = true ;
  41var $_safe_union = true ;
  42
  43var $_spamcount_uri = 0 ;
  44
  45var $_should_be_banned_time0 = false ;
  46var $_should_be_banned = false ;
  47
  48var $_dos_stage = null ;
  49
  50var $ip_matched_info = null ;
  51
  52var $last_error_type = 'UNKNOWN' ;
  53
  54
  55// Constructor
  56function Protector()
  57{
  58	$this->mydirname = 'protector' ;
  59
  60	// Preferences from configs/cache
  61	$this->_conf_serialized = @file_get_contents( $this->get_filepath4confighcache() ) ;
  62	$this->_conf = @unserialize( $this->_conf_serialized ) ;
  63	if( empty( $this->_conf ) ) $this->_conf = array() ;
  64
  65	if( ! empty( $this->_conf['global_disabled'] ) ) return true ;
  66
  67	// die if PHP_SELF XSS found (disabled in 2.53)
  68//	if( preg_match( '/[<>\'";\n ]/' , @$_SERVER['PHP_SELF'] ) ) {
  69//		$this->message .= "Invalid PHP_SELF '{$_SERVER['PHP_SELF']}' found.\n" ;
  70//		$this->output_log( 'PHP_SELF XSS' ) ;
  71//		die( 'invalid PHP_SELF' ) ;
  72//	}
  73
  74	// sanitize against PHP_SELF/PATH_INFO XSS (disabled in 3.33)
  75//	$_SERVER['PHP_SELF'] = strtr( @$_SERVER['PHP_SELF'] , array( '<' => '%3C' , '>' => '%3E' , "'" => '%27' , '"' => '%22' ) ) ;
  76//	if( ! empty( $_SERVER['PATH_INFO'] ) ) $_SERVER['PATH_INFO'] = strtr( @$_SERVER['PATH_INFO'] , array( '<' => '%3C' , '>' => '%3E' , "'" => '%27' , '"' => '%22' ) ) ;
  77
  78	$this->_bad_globals = array( 'GLOBALS' , '_SESSION' , 'HTTP_SESSION_VARS' , '_GET' , 'HTTP_GET_VARS' , '_POST' , 'HTTP_POST_VARS' , '_COOKIE' , 'HTTP_COOKIE_VARS' , '_SERVER' , 'HTTP_SERVER_VARS' , '_REQUEST' , '_ENV' , '_FILES' , 'xoopsDB' , 'xoopsUser' , 'xoopsUserId' , 'xoopsUserGroups' , 'xoopsUserIsAdmin' , 'xoopsConfig' , 'xoopsOption' , 'xoopsModule' , 'xoopsModuleConfig' ) ;
  79
  80	$this->_initial_recursive( $_GET , 'G' ) ;
  81	$this->_initial_recursive( $_POST , 'P' ) ;
  82	$this->_initial_recursive( $_COOKIE , 'C' ) ;
  83}
  84
  85
  86function _initial_recursive( $val , $key )
  87{
  88	if( is_array( $val ) ) {
  89		foreach( $val as $subkey => $subval ) {
  90			// check bad globals
  91			if( in_array( $subkey , $this->_bad_globals , true ) ) {
  92				$this->message .= "Attempt to inject '$subkey' was found.\n" ;
  93				$this->_safe_contami = false ;
  94				$this->last_error_type = 'CONTAMI' ;
  95			}
  96			$this->_initial_recursive( $subval , $key . '_' . base64_encode( $subkey ) ) ;
  97		}
  98	} else {
  99		// check nullbyte attack
 100		if( @$this->_conf['san_nullbyte'] && strstr( $val , chr(0) ) ) {
 101			$val = str_replace( chr(0) , ' ' , $val ) ;
 102			$this->replace_doubtful( $key , $val ) ;
 103			$this->message .= "Injecting Null-byte '$val' found.\n" ;
 104			$this->output_log( 'NullByte' , 0 , false , 32 ) ;
 105			// $this->purge() ;
 106		}
 107
 108		// register as doubtful requests against SQL Injections
 109		if( preg_match( '?[\s\'"`/]?' , $val ) ) {
 110			$this->_doubtful_requests["$key"] = $val ;
 111		}
 112	}
 113}
 114
 115
 116static function &getInstance()
 117{
 118	static $instance ;
 119	if( ! isset( $instance ) ) {
 120		$instance = new Protector() ;
 121	}
 122	return $instance ;
 123}
 124
 125
 126function updateConfIntoDb( $name , $value )
 127{
 128	$constpref = '_MI_' . strtoupper( $this->mydirname ) ;
 129
 130	$db =& Database::getInstance() ;
 131	$db->queryF( "UPDATE `".$db->prefix("config")."` SET `conf_value`='".addslashes($value)."' WHERE `conf_title` like '".$constpref."%' AND `conf_name`='".addslashes($name)."' LIMIT 1" ) ;
 132	$this->updateConfFromDB() ;
 133}
 134
 135
 136function updateConfFromDb()
 137{
 138	$constpref = '_MI_' . strtoupper( $this->mydirname ) ;
 139
 140	if( empty( $this->_conn ) ) return false ;
 141
 142	$result = @mysql_query( "SELECT `conf_name`,`conf_value` FROM `".XOOPS_DB_PREFIX."_config` WHERE `conf_title` like '".$constpref."%'" , $this->_conn ) ;
 143	if( ! $result || mysql_num_rows( $result ) < 5 ) {
 144		return false ;
 145	}
 146	$db_conf = array() ;
 147	while( list( $key , $val ) = mysql_fetch_row( $result ) ) {
 148		$db_conf[ $key ] = $val ;
 149	}
 150	$db_conf_serialized = serialize( $db_conf ) ;
 151
 152	// update config cache
 153	if( $db_conf_serialized != $this->_conf_serialized ) {
 154		$fp = fopen( $this->get_filepath4confighcache() , 'w' ) ;
 155		fwrite( $fp , $db_conf_serialized ) ;
 156		fclose( $fp ) ;
 157		$this->_conf = $db_conf ;
 158	}
 159	return true ;
 160}
 161
 162
 163function setConn( $conn )
 164{
 165	$this->_conn = $conn ;
 166}
 167
 168
 169function getConf()
 170{
 171	return $this->_conf ;
 172}
 173
 174
 175function purge( $redirect_to_top = false )
 176{
 177	// clear all session values
 178	if( isset( $_SESSION ) ) foreach( $_SESSION as $key => $val ) {
 179		$_SESSION[ $key ] = '' ;
 180		if( isset( $GLOBALS[ $key ] ) ) $GLOBALS[ $key ] = '' ;
 181	}
 182
 183	if( ! headers_sent() ) {
 184		// clear typical session id of PHP
 185		setcookie( 'PHPSESSID' , '' , time() - 3600 , '/' , '' , 0 ) ;
 186		if( isset( $_COOKIE[ session_name() ] ) ) {
 187			setcookie( session_name() , '' , time() - 3600 , '/' , '' , 0 ) ;
 188		}
 189
 190		// clear autologin cookie
 191		$xoops_cookie_path = defined('XOOPS_COOKIE_PATH') ? XOOPS_COOKIE_PATH : preg_replace( '?http://[^/]+(/.*)$?' , "$1" , XOOPS_URL ) ;
 192		if( $xoops_cookie_path == XOOPS_URL ) $xoops_cookie_path = '/' ;
 193		setcookie('autologin_uname', '', time() - 3600, $xoops_cookie_path, '', 0);
 194		setcookie('autologin_pass', '', time() - 3600, $xoops_cookie_path, '', 0);
 195	}
 196
 197	if( $redirect_to_top ) {
 198		header( 'Location: '.XOOPS_URL.'/' ) ;
 199		exit ;
 200	} else {
 201		$ret = $this->call_filter( 'prepurge_exit' ) ;
 202		if( $ret == false ) {
 203			die( 'Protector detects attacking actions' ) ;
 204		}
 205	}
 206}
 207
 208
 209function output_log( $type = 'UNKNOWN' , $uid = 0 , $unique_check = false , $level = 1 )
 210{
 211	if( $this->_logged ) return true ;
 212
 213	if( ! ( $this->_conf['log_level'] & $level ) ) return true ;
 214
 215	if( empty( $this->_conn ) ) {
 216		$this->_conn = @mysql_connect( XOOPS_DB_HOST , XOOPS_DB_USER , XOOPS_DB_PASS ) ;
 217		if( ! $this->_conn ) die( 'db connection failed.' ) ;
 218		if( ! mysql_select_db( XOOPS_DB_NAME , $this->_conn ) ) die( 'db selection failed.' ) ;
 219	}
 220
 221	$ip = @$_SERVER['REMOTE_ADDR'] ;
 222	$agent = @$_SERVER['HTTP_USER_AGENT'] ;
 223
 224	if( $unique_check ) {
 225		$result = mysql_query( 'SELECT ip,type FROM '.XOOPS_DB_PREFIX.'_'.$this->mydirname.'_log ORDER BY timestamp DESC LIMIT 1' , $this->_conn ) ;
 226		list( $last_ip , $last_type ) = mysql_fetch_row( $result ) ;
 227		if( $last_ip == $ip && $last_type == $type ) {
 228			$this->_logged = true ;
 229			return true ;
 230		}
 231	}
 232
 233	mysql_query( "INSERT INTO ".XOOPS_DB_PREFIX."_".$this->mydirname."_log SET ip='".addslashes($ip)."',agent='".addslashes($agent)."',type='".addslashes($type)."',description='".addslashes($this->message)."',uid='".intval($uid)."',timestamp=NOW()" , $this->_conn ) ;
 234	$this->_logged = true ;
 235	return true ;
 236}
 237
 238
 239function write_file_bwlimit( $expire )
 240{
 241	$expire = min( intval( $expire ) , time() + 300 ) ;
 242
 243	$fp = @fopen( $this->get_filepath4bwlimit() , 'w' ) ;
 244	if( $fp ) {
 245		@flock( $fp , LOCK_EX ) ;
 246		fwrite( $fp , $expire . "\n" ) ;
 247		@flock( $fp , LOCK_UN ) ;
 248		fclose( $fp ) ;
 249		return true ;
 250	} else {
 251		return false ;
 252	}
 253}
 254
 255
 256function get_bwlimit()
 257{
 258	list( $expire ) = @file( Protector::get_filepath4bwlimit() ) ;
 259	$expire = min( intval( $expire ) , time() + 300 ) ;
 260
 261	return $expire ;
 262}
 263
 264
 265function get_filepath4bwlimit()
 266{
 267	return XOOPS_TRUST_PATH . '/modules/protector/configs/bwlimit' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
 268}
 269
 270
 271function write_file_badips( $bad_ips )
 272{
 273	asort( $bad_ips ) ;
 274
 275	$fp = @fopen( $this->get_filepath4badips() , 'w' ) ;
 276	if( $fp ) {
 277		@flock( $fp , LOCK_EX ) ;
 278		fwrite( $fp , serialize( $bad_ips ) . "\n" ) ;
 279		@flock( $fp , LOCK_UN ) ;
 280		fclose( $fp ) ;
 281		return true ;
 282	} else {
 283		return false ;
 284	}
 285}
 286
 287
 288function register_bad_ips( $jailed_time = 0 , $ip = null )
 289{
 290	if( empty( $ip ) ) $ip = @$_SERVER['REMOTE_ADDR'] ;
 291	if( empty( $ip ) ) return false ;
 292
 293	$bad_ips = $this->get_bad_ips( true ) ;
 294	$bad_ips[ $ip ] = $jailed_time ? $jailed_time : 0x7fffffff ;
 295
 296	return $this->write_file_badips( $bad_ips ) ;
 297}
 298
 299
 300function get_bad_ips( $with_jailed_time = false )
 301{
 302	list( $bad_ips_serialized ) = @file( Protector::get_filepath4badips() ) ;
 303	$bad_ips = empty( $bad_ips_serialized ) ? array() : @unserialize( $bad_ips_serialized ) ;
 304	if( ! is_array( $bad_ips ) || isset( $bad_ips[0] ) ) $bad_ips = array() ;
 305
 306	// expire jailed_time
 307	$pos = 0 ;
 308	foreach( $bad_ips as $bad_ip => $jailed_time ) {
 309		if( $jailed_time >= time() ) break ;
 310		$pos ++ ;
 311	}
 312	$bad_ips = array_slice( $bad_ips , $pos ) ;
 313
 314	if( $with_jailed_time ) {
 315		return $bad_ips ;
 316	} else {
 317		return array_keys( $bad_ips ) ;
 318	}
 319}
 320
 321
 322function get_filepath4badips()
 323{
 324	return XOOPS_TRUST_PATH . '/modules/protector/configs/badips' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
 325}
 326
 327
 328function get_group1_ips( $with_info = false )
 329{
 330	list( $group1_ips_serialized ) = @file( Protector::get_filepath4group1ips() ) ;
 331	$group1_ips = empty( $group1_ips_serialized ) ? array() : @unserialize( $group1_ips_serialized ) ;
 332	if( ! is_array( $group1_ips ) ) $group1_ips = array() ;
 333
 334	if( $with_info ) {
 335		$group1_ips = array_flip( $group1_ips ) ;
 336	}
 337
 338	return $group1_ips ;
 339}
 340
 341
 342function get_filepath4group1ips()
 343{
 344	return XOOPS_TRUST_PATH . '/modules/protector/configs/group1ips' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
 345}
 346
 347
 348function get_filepath4confighcache()
 349{
 350	return XOOPS_TRUST_PATH . '/modules/protector/configs/configcache' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
 351}
 352
 353
 354function ip_match( $ips )
 355{
 356	foreach( $ips as $ip => $info ) {
 357		if( $ip ) {
 358			switch( substr( $ip , -1 ) ) {
 359				case '.' :
 360					// foward match
 361					if( substr( @$_SERVER['REMOTE_ADDR'] , 0 , strlen( $ip ) ) == $ip ) {
 362						$this->ip_matched_info = $info ;
 363						return true ;
 364					}
 365					break ;
 366				case '0' :
 367				case '1' :
 368				case '2' :
 369				case '3' :
 370				case '4' :
 371				case '5' :
 372				case '6' :
 373				case '7' :
 374				case '8' :
 375				case '9' :
 376					// full match
 377					if( @$_SERVER['REMOTE_ADDR'] == $ip ) {
 378						$this->ip_matched_info = $info ;
 379						return true ;
 380					}
 381					break ;
 382				default :
 383					// perl regex
 384					if( @preg_match( $ip , @$_SERVER['REMOTE_ADDR'] ) ) {
 385						$this->ip_matched_info = $info ;
 386						return true ;
 387					}
 388					break ;
 389			}
 390		}
 391	}
 392	$this->ip_matched_info = null ;
 393	return false ;
 394}
 395
 396
 397function deny_by_htaccess( $ip = null )
 398{
 399	if( empty( $ip ) ) $ip = @$_SERVER['REMOTE_ADDR'] ;
 400	if( empty( $ip ) ) return false ;
 401	if( ! function_exists( 'file_get_contents' ) ) return false ;
 402
 403	$target_htaccess = XOOPS_ROOT_PATH.'/.htaccess' ;
 404	$backup_htaccess = XOOPS_ROOT_PATH.'/uploads/.htaccess.bak' ;
 405
 406	$ht_body = file_get_contents( $target_htaccess ) ;
 407
 408	// make backup as uploads/.htaccess.bak automatically
 409	if( $ht_body && ! file_exists( $backup_htaccess ) ) {
 410		$fw = fopen( $backup_htaccess , "w" ) ;
 411		fwrite( $fw , $ht_body ) ;
 412		fclose( $fw ) ;
 413	}
 414
 415	// if .htaccess is broken, restore from backup
 416	if( ! $ht_body && file_exists( $backup_htaccess ) ) {
 417		$ht_body = file_get_contents( $backup_htaccess ) ;
 418	}
 419
 420	// new .htaccess
 421	if( $ht_body === false ) {
 422		$ht_body = '' ;
 423	}
 424
 425	if( preg_match( "/^(.*)#PROTECTOR#\s+(DENY FROM .*)\n#PROTECTOR#\n(.*)$/si" , $ht_body , $regs ) ) {
 426		if( substr( $regs[2] , - strlen( $ip ) ) == $ip ) return true ;
 427		$new_ht_body = $regs[1] . "#PROTECTOR#\n" . $regs[2] . " $ip\n#PROTECTOR#\n" . $regs[3] ;
 428	} else {
 429		$new_ht_body = "#PROTECTOR#\nDENY FROM $ip\n#PROTECTOR#\n" . $ht_body ;
 430	}
 431
 432	// error_log( "$new_ht_body\n" , 3 , "/tmp/error_log" ) ;
 433
 434	$fw = fopen( $target_htaccess , "w" ) ;
 435	@flock( $fw , LOCK_EX ) ;
 436	fwrite( $fw , $new_ht_body ) ;
 437	@flock( $fw , LOCK_UN ) ;
 438	fclose( $fw ) ;
 439
 440	return true ;
 441}
 442
 443
 444function getDblayertrapDoubtfuls()
 445{
 446	return $this->_dblayertrap_doubtfuls ;
 447}
 448
 449
 450function _dblayertrap_check_recursive( $val )
 451{
 452	if( is_array( $val ) ) {
 453		foreach( $val as $subval ) {
 454			$this->_dblayertrap_check_recursive( $subval ) ;
 455		}
 456	} else {
 457		if( strlen( $val ) < 6 ) return ;
 458		$val = get_magic_quotes_gpc() ? stripslashes( $val ) : $val ;
 459		foreach( $this->_dblayertrap_doubtful_needles as $needle ) {
 460			if( stristr( $val , $needle ) ) {
 461				$this->_dblayertrap_doubtfuls[] = $val ;
 462			}
 463		}
 464	}
 465}
 466
 467
 468function dblayertrap_init( $force_override = false )
 469{
 470	if( ! empty( $GLOBALS['xoopsOption']['nocommon'] ) || defined( '_XCORE_PREVENT_EXEC_COMMON_' ) || defined( '_XCORE_PREVENT_LOAD_CORE_' ) ) return ; // skip
 471
 472	$this->_dblayertrap_doubtfuls = array() ;
 473	$this->_dblayertrap_check_recursive( $_GET ) ;
 474	$this->_dblayertrap_check_recursive( $_POST ) ;
 475	$this->_dblayertrap_check_recursive( $_COOKIE ) ;
 476	if( empty( $this->_conf['dblayertrap_wo_server'] ) ) {
 477		$this->_dblayertrap_check_recursive( $_SERVER ) ;
 478	}
 479
 480	if( ! empty( $this->_dblayertrap_doubtfuls ) || $force_override ) {
 481		@define( 'XOOPS_DB_ALTERNATIVE' , 'ProtectorMysqlDatabase' ) ;
 482		require_once dirname(dirname(__FILE__)).'/class/ProtectorMysqlDatabase.class.php' ;
 483	}
 484}
 485
 486
 487function _bigumbrella_check_recursive( $val )
 488{
 489	if( is_array( $val ) ) {
 490		foreach( $val as $subval ) {
 491			$this->_bigumbrella_check_recursive( $subval ) ;
 492		}
 493	} else {
 494		if( preg_match( '/[<\'"].{15}/s' , $val , $regs ) ) {
 495			$this->_bigumbrella_doubtfuls[] = $regs[0] ;
 496		}
 497	}
 498}
 499
 500
 501function bigumbrella_init()
 502{
 503	$this->_bigumbrella_doubtfuls = array() ;
 504	$this->_bigumbrella_check_recursive( $_GET ) ;
 505	$this->_bigumbrella_check_recursive( @$_SERVER['PHP_SELF'] ) ;
 506
 507	if( ! empty( $this->_bigumbrella_doubtfuls ) ) {
 508		ob_start( array( $this , 'bigumbrella_outputcheck' ) ) ;
 509	}
 510}
 511
 512
 513function bigumbrella_outputcheck( $s )
 514{
 515	if( defined( 'BIGUMBRELLA_DISABLED' ) ) return $s ;
 516
 517	if( function_exists( 'headers_list' ) ) {
 518		foreach( headers_list() as $header ) {
 519			if( stristr( $header , 'Content-Type:' ) && ! stristr( $header , 'text/html' ) ) {
 520				return $s ;
 521			}
 522		}
 523	}
 524
 525	if( ! is_array( $this->_bigumbrella_doubtfuls ) ) {
 526		return "bigumbrella injection found." ;
 527	}
 528
 529	foreach( $this->_bigumbrella_doubtfuls as $doubtful ) {
 530		if( strstr( $s , $doubtful ) ) {
 531			return "XSS found by Protector." ;
 532		}
 533	}
 534	return $s ;
 535}
 536
 537
 538function intval_allrequestsendid()
 539{
 540	global $HTTP_GET_VARS , $HTTP_POST_VARS , $HTTP_COOKIE_VARS ;
 541
 542	if( $this->_done_intval ) return true ;
 543	else $this->_done_intval = true ;
 544
 545	foreach( $_GET as $key => $val ) {
 546		if( substr( $key , -2 ) == 'id' && ! is_array( $_GET[ $key ] ) ) {
 547			$newval = preg_replace( '/[^0-9a-zA-Z_-]/' , '' , $val ) ;
 548			if( isset( $_REQUEST[ $key ] ) && $_REQUEST[ $key ] == $_GET[ $key ] ){
 549				$_REQUEST[ $key ] = $newval ;
 550			}
 551			$_GET[ $key ] = $HTTP_GET_VARS[ $key ] = $newval ;
 552		}
 553	}
 554	foreach( $_POST as $key => $val ) {
 555		if( substr( $key , -2 ) == 'id' && ! is_array( $_POST[ $key ] ) ) {
 556			$newval = preg_replace( '/[^0-9a-zA-Z_-]/' , '' , $val ) ;
 557			if( isset( $_REQUEST[ $key ] ) && $_REQUEST[ $key ] == $_POST[ $key ] ){
 558				$_REQUEST[ $key ] = $newval ;
 559			}
 560			$_POST[ $key ] = $HTTP_POST_VARS[ $key ] = $newval ;
 561		}
 562	}
 563	foreach( $_COOKIE as $key => $val ) {
 564		if( substr( $key , -2 ) == 'id' && ! is_array( $_COOKIE[ $key ] ) ) {
 565			$newval = preg_replace( '/[^0-9a-zA-Z_-]/' , '' , $val ) ;
 566			if( isset( $_REQUEST[ $key ] ) && $_REQUEST[ $key ] == $_COOKIE[ $key ] ){
 567				$_REQUEST[ $key ] = $newval ;
 568			}
 569			$_COOKIE[ $key ] = $HTTP_COOKIE_VARS[ $key ] = $newval ;
 570		}
 571	}
 572
 573	return true ;
 574}
 575
 576
 577function eliminate_dotdot()
 578{
 579	global $HTTP_GET_VARS , $HTTP_POST_VARS , $HTTP_COOKIE_VARS ;
 580
 581	if( $this->_done_dotdot ) return true ;
 582	else $this->_done_dotdot = true ;
 583
 584	foreach( $_GET as $key => $val ) {
 585		if( is_array( $_GET[ $key ] ) ) continue ;
 586		if( substr( trim( $val ) , 0 , 3 ) == '../' || strstr( $val , '../../' ) ) {
 587			$this->last_error_type = 'DirTraversal' ;
 588			$this->message .= "Directory Traversal '$val' found.\n" ;
 589			$this->output_log( $this->last_error_type , 0 , false , 64 ) ;
 590			$sanitized_val = str_replace( chr(0) , '' , $val ) ;
 591			if( substr( $sanitized_val , -2 ) != ' .' ) $sanitized_val .= ' .' ;
 592			$_GET[ $key ] = $HTTP_GET_VARS[ $key ] = $sanitized_val ;
 593			if( $_REQUEST[ $key ] == $_GET[ $key ] ){
 594				$_REQUEST[ $key ] = $sanitized_val ;
 595			}
 596		}
 597	}
 598/*	foreach( $_POST as $key => $val ) {
 599		if( is_array( $_POST[ $key ] ) ) continue ;
 600		if( substr( trim( $val ) , 0 , 3 ) == '../' || strstr( $val , '../../' ) ) {
 601			$this->last_error_type = 'ParentDir' ;
 602			$this->message .= "Doubtful file specification '$val' found.\n" ;
 603			$this->output_log( $this->last_error_type , 0 , false , 128 ) ;
 604			$sanitized_val = str_replace( chr(0) , '' , $val ) ;
 605			if( substr( $sanitized_val , -2 ) != ' .' ) $sanitized_val .= ' .' ;
 606			$_POST[ $key ] = $HTTP_POST_VARS[ $key ] = $sanitized_val ;
 607			if( $_REQUEST[ $key ] == $_POST[ $key ] ){
 608				$_REQUEST[ $key ] = $sanitized_val ;
 609			}
 610		}
 611	}
 612	foreach( $_COOKIE as $key => $val ) {
 613		if( is_array( $_COOKIE[ $key ] ) ) continue ;
 614		if( substr( trim( $val ) , 0 , 3 ) == '../' || strstr( $val , '../../' ) ) {
 615			$this->last_error_type = 'ParentDir' ;
 616			$this->message .= "Doubtful file specification '$val' found.\n" ;
 617			$this->output_log( $this->last_error_type , 0 , false , 128 ) ;
 618			$sanitized_val = str_replace( chr(0) , '' , $val ) ;
 619			if( substr( $sanitized_val , -2 ) != ' .' ) $sanitized_val .= ' .' ;
 620			$_COOKIE[ $key ] = $HTTP_COOKIE_VARS[ $key ] = $sanitized_val ;
 621			if( $_REQUEST[ $key ] == $_COOKIE[ $key ] ){
 622				$_REQUEST[ $key ] = $sanitized_val ;
 623			}
 624		}
 625	}*/
 626
 627	return true ;
 628}
 629
 630
 631function &get_ref_from_base64index( &$current , $indexes )
 632{
 633	foreach( $indexes as $index ) {
 634		$index = base64_decode( $index ) ;
 635		if( ! is_array( $current ) ) return false ;
 636		$current =& $current[ $index ] ;
 637	}
 638	return $current ;
 639}
 640
 641
 642function replace_doubtful( $key , $val )
 643{
 644	global $HTTP_GET_VARS , $HTTP_POST_VARS , $HTTP_COOKIE_VARS ;
 645
 646	$index_expression = '' ;
 647	$indexes = explode( '_' , $key ) ;
 648	$base_array = array_shift( $indexes ) ;
 649
 650	switch( $base_array ) {
 651		case 'G' :
 652			$main_ref =& $this->get_ref_from_base64index( $_GET , $indexes ) ;
 653			$xcore_ref =& $this->get_ref_from_base64index( $HTTP_GET_VARS , $indexes ) ;
 654			break ;
 655		case 'P' :
 656			$main_ref =& $this->get_ref_from_base64index( $_POST , $indexes ) ;
 657			$xcore_ref =& $this->get_ref_from_base64index( $HTTP_POST_VARS , $indexes ) ;
 658			break ;
 659		case 'C' :
 660			$main_ref =& $this->get_ref_from_base64index( $_COOKIE , $indexes ) ;
 661			$xcore_ref =& $this->get_ref_from_base64index( $HTTP_COOKIE_VARS , $indexes ) ;
 662			break ;
 663		default :
 664			exit ;
 665	}
 666	if( ! isset( $main_ref ) ) exit ;
 667	$request_ref =& $this->get_ref_from_base64index( $_REQUEST , $indexes ) ;
 668	if( $request_ref !== false && $main_ref == $request_ref ) {
 669		$request_ref = $val ;
 670	}
 671	$main_ref = $val ;
 672	$xcore_ref = $val ;
 673}
 674
 675
 676function check_uploaded_files()
 677{
 678	if( $this->_done_badext ) return $this->_safe_badext ;
 679	else $this->_done_badext = true ;
 680
 681	// extensions never uploaded
 682	$bad_extensions = array( 'php' , 'phtml' , 'phtm' , 'php3' , 'php4' , 'cgi' , 'pl' , 'asp' ) ;
 683	// extensions needed image check (anti-IE Content-Type XSS)
 684	$image_extensions = array( 1 => 'gif', 2 => 'jpg', 3 => 'png', 4 => 'swf', 5 => 'psd', 6 => 'bmp', 7 => 'tif', 8 => 'tif', 9 => 'jpc', 10 => 'jp2', 11 => 'jpx', 12 => 'jb2', 13 => 'swc', 14 => 'iff', 15 => 'wbmp', 16 => 'xbm' ) ;
 685
 686	foreach( $_FILES as $_file ) {
 687		if( ! empty( $_file['error'] ) ) continue ;
 688		if( ! empty( $_file['name'] ) && is_string( $_file['name'] ) ) {
 689			$ext = strtolower( substr( strrchr( $_file['name'] , '.' ) , 1 ) ) ;
 690			if( $ext == 'jpeg' ) $ext = 'jpg' ;
 691			else if( $ext == 'tiff' ) $ext = 'tif' ;
 692			else if( $ext == 'swc' ) $ext = 'swf' ;
 693
 694			// anti multiple dot file (Apache mod_mime.c)
 695			if( count( explode( '.' , str_replace( '.tar.gz' , '.tgz' , $_file['name'] ) ) ) > 2 ) {
 696				$this->message .= "Attempt to multiple dot file {$_file['name']}.\n" ;
 697				$this->_safe_badext = false ;
 698				$this->last_error_type = 'UPLOAD' ;
 699			}
 700
 701			// anti dangerous extensions
 702			if( in_array( $ext , $bad_extensions ) ) {
 703				$this->message .= "Attempt to upload {$_file['name']}.\n" ;
 704				$this->_safe_badext = false ;
 705				$this->last_error_type = 'UPLOAD' ;
 706			}
 707
 708			// anti camouflaged image file
 709			if( in_array( $ext , $image_extensions ) ) {
 710				$image_attributes = @getimagesize( $_file['tmp_name'] ) ;
 711				if( $image_attributes === false && is_uploaded_file( $_file['tmp_name'] ) ) {
 712					// open_basedir restriction
 713					$temp_file = XOOPS_ROOT_PATH.'/uploads/protector_upload_temporary'.md5( time() ) ;
 714					move_uploaded_file( $_file['tmp_name'] , $temp_file ) ;
 715					$image_attributes = @getimagesize( $temp_file ) ;
 716					@unlink( $temp_file ) ;
 717				}
 718
 719				$imagetype = intval( $image_attributes[2] ) ;
 720				if( $imagetype == IMAGETYPE_SWC ) $imagetype = IMAGETYPE_SWF ;
 721				if( $image_attributes === false || $image_extensions[ $imagetype ] != $ext ) {
 722					$this->message .= "Attempt to upload camouflaged image file {$_file['name']}.\n" ;
 723					$this->_safe_badext = false ;
 724					$this->last_error_type = 'UPLOAD' ;
 725				}
 726			}
 727		}
 728	}
 729
 730	return $this->_safe_badext ;
 731}
 732
 733
 734function check_contami_systemglobals()
 735{
 736/*	if( $this->_done_contami ) return $this->_safe_contami ;
 737	else $this->_done_contami = true ; */
 738
 739/*	foreach( $this->_bad_globals as $bad_global ) {
 740		if( isset( $_REQUEST[ $bad_global ] ) ) {
 741			$this->message .= "Attempt to inject '$bad_global' was found.\n" ;
 742			$this->_safe_contami = false ;
 743			$this->last_error_type = 'CONTAMI' ;
 744		}
 745	}*/
 746
 747	return $this->_safe_contami ;
 748}
 749
 750
 751function check_sql_isolatedcommentin( $sanitize = true )
 752{
 753	if( $this->_done_isocom ) return $this->_safe_isocom ;
 754	else $this->_done_isocom = true ;
 755
 756	foreach( $this->_doubtful_requests as $key => $val ) {
 757		$str = $val ;
 758		while( $str = strstr( $str , '/*' ) ) { /* */
 759			$str = strstr( substr( $str , 2 ) , '*/' ) ;
 760			if( $str === false ) {
 761				$this->message .= "Isolated comment-in found. ($val)\n" ;
 762				if( $sanitize ) $this->replace_doubtful( $key , $val . '*/' ) ;
 763				$this->_safe_isocom = false ;
 764				$this->last_error_type = 'ISOCOM' ;
 765			}
 766		}
 767	}
 768	return $this->_safe_isocom ;
 769}
 770
 771
 772function check_sql_union( $sanitize = true )
 773{
 774	if( $this->_done_union ) return $this->_safe_union ;
 775	else $this->_done_union = true ;
 776
 777	foreach( $this->_doubtful_requests as $key => $val ) {
 778
 779		$str = str_replace( array( '/*' , '*/' ) , '' , preg_replace( '?/\*.+\*/?sU' , '' , $val ) ) ;
 780		if( preg_match( '/\sUNION\s+(ALL|SELECT)/i' , $str ) ) {
 781			$this->message .= "Pattern like SQL injection found. ($val)\n" ;
 782			if( $sanitize ) $this->replace_doubtful( $key , preg_replace( '/union/i' , 'uni-on' , $val ) ) ;
 783			$this->_safe_union = false ;
 784			$this->last_error_type = 'UNION' ;
 785		}
 786	}
 787	return $this->_safe_union ;
 788}
 789
 790
 791function check_dos_attack( $uid = 0 , $can_ban = false )
 792{
 793	global $xoopsDB ;
 794
 795	if( $this->_done_dos ) return true ;
 796
 797	$ip = @$_SERVER['REMOTE_ADDR'] ;
 798	$uri = @$_SERVER['REQUEST_URI'] ;
 799	$ip4sql = addslashes( $ip ) ;
 800	$uri4sql = addslashes( $uri ) ;
 801	if( empty( $ip ) || $ip == '' ) return true ;
 802
 803	// gargage collection
 804	$result = $xoopsDB->queryF( "DELETE FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE expire < UNIX_TIMESTAMP()" ) ;
 805
 806	// for older versions before updating this module
 807	if( $result === false ) {
 808		$this->_done_dos = true ;
 809		return true ;
 810	}
 811
 812	// sql for recording access log (INSERT should be placed after SELECT)
 813	$sql4insertlog = "INSERT INTO ".$xoopsDB->prefix($this->mydirname."_access")." SET ip='$ip4sql',request_uri='$uri4sql',expire=UNIX_TIMESTAMP()+'".intval($this->_conf['dos_expire'])."'" ;
 814
 815	// bandwidth limitation
 816	if( @$this->_conf['bwlimit_count'] >= 10 ) {
 817		$result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access") ) ;
 818		list( $bw_count ) = $xoopsDB->fetchRow( $result ) ;
 819		if( $bw_count > $this->_conf['bwlimit_count'] ) {
 820			$this->write_file_bwlimit( time() + $this->_conf['dos_expire'] ) ;
 821		}
 822	}
 823
 824	// F5 attack check (High load & same URI)
 825	$result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE ip='$ip4sql' AND request_uri='$uri4sql'" ) ;
 826	list( $f5_count ) = $xoopsDB->fetchRow( $result ) ;
 827	if( $f5_count > $this->_conf['dos_f5count'] ) {
 828
 829		// delayed insert
 830		$xoopsDB->queryF( $sql4insertlog ) ;
 831
 832		// extends the expires of the IP with 5 minutes at least (pending)
 833		// $result = $xoopsDB->queryF( "UPDATE ".$xoopsDB->prefix($this->mydirname."_access")." SET expire=UNIX_TIMESTAMP()+300 WHERE ip='$ip4sql' AND expire<UNIX_TIMESTAMP()+300" ) ;
 834
 835		// call the filter first
 836		$ret = $this->call_filter( 'f5attack_overrun' ) ;
 837
 838		// actions for F5 Attack
 839		$this->_done_dos = true ;
 840		$this->last_error_type = 'DoS' ;
 841		switch( $this->_conf['dos_f5action'] ) {
 842			default :
 843			case 'exit' :
 844				$this->output_log( $this->last_error_type , $uid , true , 16 ) ;
 845				exit ;
 846			case 'none' :
 847				$this->output_log( $this->last_error_type , $uid , true , 16 ) ;
 848				return true ;
 849			case 'biptime0' :
 850				if( $can_ban ) $this->register_bad_ips( time() + $this->_conf['banip_time0'] ) ;
 851				break ;
 852			case 'bip' :
 853				if( $can_ban ) $this->register_bad_ips() ;
 854				break ;
 855			case 'hta' :
 856				if( $can_ban ) $this->deny_by_htaccess() ;
 857				break ;
 858			case 'sleep' :
 859				sleep( 5 ) ;
 860				break ;
 861		}
 862		return false ;
 863	}
 864
 865	// Check its Agent
 866	if( trim( $this->_conf['dos_crsafe'] ) != '' && preg_match( $this->_conf['dos_crsafe'] , @$_SERVER['HTTP_USER_AGENT'] ) ) {
 867		// welcomed crawler
 868		$this->_done_dos = true ;
 869		return true ;
 870	}
 871
 872	// Crawler check (High load & different URI)
 873	$result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE ip='$ip4sql'" ) ;
 874	list( $crawler_count ) = $xoopsDB->fetchRow( $result ) ;
 875
 876	// delayed insert
 877	$xoopsDB->queryF( $sql4insertlog ) ;
 878
 879	if( $crawler_count > $this->_conf['dos_crcount'] ) {
 880
 881		// call the filter first
 882		$ret = $this->call_filter( 'crawler_overrun' ) ;
 883
 884		// actions for bad Crawler
 885		$this->_done_dos = true ;
 886		$this->last_error_type = 'CRAWLER' ;
 887		switch( $this->_conf['dos_craction'] ) {
 888			default :
 889			case 'exit' :
 890				$this->output_log( $this->last_error_type , $uid , true , 16 ) ;
 891				exit ;
 892			case 'none' :
 893				$this->output_log( $this->last_error_type , $uid , true , 16 ) ;
 894				return true ;
 895			case 'biptime0' :
 896				if( $can_ban ) $this->register_bad_ips( time() + $this->_conf['banip_time0'] ) ;
 897				break ;
 898			case 'bip' :
 899				if( $can_ban ) $this->register_bad_ips() ;
 900				break ;
 901			case 'hta' :
 902				if( $can_ban ) $this->deny_by_htaccess() ;
 903				break ;
 904			case 'sleep' :
 905				sleep( 5 ) ;
 906				break ;
 907		}
 908		return false ;
 909	}
 910
 911	return true ;
 912}
 913
 914
 915//
 916function check_brute_force()
 917{
 918	global $xoopsDB ;
 919
 920	$ip = @$_SERVER['REMOTE_ADDR'] ;
 921	$uri = @$_SERVER['REQUEST_URI'] ;
 922	$ip4sql = addslashes( $ip ) ;
 923	$uri4sql = addslashes( $uri ) ;
 924	if( empty( $ip ) || $ip == '' ) return true ;
 925
 926	$victim_uname = empty( $_COOKIE['autologin_uname'] ) ? $_POST['uname'] : $_COOKIE['autologin_uname'] ;
 927	// some UA send 'deleted' as a value of the deleted cookie.
 928	if( $victim_uname == 'deleted' ) return ;
 929	$mal4sql = addslashes( "BRUTE FORCE: $victim_uname" ) ;
 930
 931	// gargage collection
 932	$result = $xoopsDB->queryF( "DELETE FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE expire < UNIX_TIMESTAMP()" ) ;
 933
 934	// sql for recording access log (INSERT should be placed after SELECT)
 935	$sql4insertlog = "INSERT INTO ".$xoopsDB->prefix($this->mydirname."_access")." SET ip='$ip4sql',request_uri='$uri4sql',malicious_actions='$mal4sql',expire=UNIX_TIMESTAMP()+600" ;
 936
 937	// count check
 938	$result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE ip='$ip4sql' AND malicious_actions like 'BRUTE FORCE:%'" ) ;
 939	list( $bf_count ) = $xoopsDB->fetchRow( $result ) ;
 940	if( $bf_count > $this->_conf['bf_count'] ) {
 941		$this->register_bad_ips( time() + $this->_conf['banip_time0'] ) ;
 942		$this->last_error_type = 'BruteForce' ;
 943		$this->message .= "Trying to login as '".addslashes($victim_uname)."' found.\n" ;
 944		$this->output_log( 'BRUTE FORCE' , 0 , true , 1 ) ;
 945		$ret = $this->call_filter( 'bruteforce_overrun' ) ;
 946		if( $ret == false ) exit ;
 947	}
 948	// delayed insert
 949	$xoopsDB->queryF( $sql4insertlog ) ;
 950}
 951
 952
 953function _spam_check_point_recursive( $val )
 954{
 955	if( is_array( $val ) ) {
 956		foreach( $val as $subval ) {
 957			$this->_spam_check_point_recursive( $subval ) ;
 958		}
 959	} else {
 960		// http_host
 961		$path_array = parse_url( XOOPS_URL ) ;
 962		$http_host = empty( $path_array['host'] ) ? 'www.xoops.org' : $path_array['host'] ;
 963
 964		// count URI up
 965		$count = -1 ;
 966		foreach( preg_split( '#https?\:\/\/#i' , $val ) as $fragment ) {
 967			if( strncmp( $fragment , $http_host , strlen( $http_host ) ) !== 0 ) {
 968				$count ++ ;
 969			}
 970		}
 971		if( $count > 0 ) $this->_spamcount_uri += $count ;
 972
 973		// count BBCode likd [url=www....] up (without [url=http://...])
 974		$this->_spamcount_uri += count( preg_split( '/\[url=(?!http|\\"http|\\\'http|'.$http_host.')/i' , $val ) ) - 1 ;
 975	}
 976}
 977
 978
 979function spam_check( $points4deny , $uid )
 980{
 981	$this->_spamcount_uri = 0 ;
 982	$this->_spam_check_point_recursive( $_POST ) ;
 983
 984	if( $this->_spamcount_uri >= $points4deny ) {
 985		$this->message .= @$_SERVER['REQUEST_URI']." SPAM POINT: $this->_spamcount_uri\n" ;
 986		$this->output_log( 'URI SPAM' , $uid , false , 128 ) ;
 987		$ret = $this->call_filter( 'spamcheck_overrun' ) ;
 988		if( $ret == false ) exit ;
 989	}
 990}
 991
 992
 993function check_manipulation()
 994{
 995	if( $_SERVER['SCRIPT_FILENAME'] == XOOPS_ROOT_PATH.'/index.php' ) {
 996		$root_stat = stat( XOOPS_ROOT_PATH ) ;
 997		$index_stat = stat( XOOPS_ROOT_PATH.'/index.php' ) ;
 998		$finger_print = $root_stat['mtime'] .':'. $index_stat['mtime'] .':'. $index_stat['ino'] ;
 999		if( empty( $this->_conf['manip_value'] ) ) {
1000			$this->updateConfIntoDb( 'manip_value' , $finger_print ) ;
1001		} else if( $finger_print != $this->_conf['manip_value'] ) {
1002			// Notify if finger_print is ident from old one
1003			$ret = $this->call_filter( 'postcommon_manipu' ) ;
1004			if( $ret == false ) die( 'Protector detects site manipulation.' ) ;
1005			$this->updateConfIntoDb( 'manip_value' , $finger_print ) ;
1006		}
1007	}
1008
1009}
1010
1011
1012function disable_features()
1013{
1014	global $HTTP_POST_VARS , $HTTP_GET_VARS , $HTTP_COOKIE_VARS ;
1015
1016
1017	// disable "Notice: Undefined index: ..."
1018	$error_reporting_level = error_reporting( 0 ) ;
1019
1020
1021	//
1022	// bit 1 : disable XMLRPC , criteria bug
1023	//
1024	if( $this->_conf['disable_features'] & 1 ) {
1025
1026		// zx 2005/1/5 disable xmlrpc.php in root
1027		if( /* ! stristr( $_SERVER['SCRIPT_NAME'] , 'modules' ) && */ substr( @$_SERVER['SCRIPT_NAME'] , -10 ) == 'xmlrpc.php' ) {
1028			$this->output_log( 'xmlrpc' , 0 , true , 1 ) ;
1029			exit ;
1030		}
1031
1032		// security bug of class/criteria.php 2005/6/27
1033		if( $_POST['uname'] === '0' || $_COOKIE['autologin_pass'] === '0' ) {
1034			$this->output_log( 'CRITERIA' ) ;
1035			exit ;
1036		}
1037	}
1038
1039
1040	//
1041	// bit 11 : XSS+CSRFs in XOOPS < 2.0.10
1042	//
1043	if( $this->_conf['disable_features'] & 1024 ) {
1044
1045		// root controllers
1046		if( ! stristr( @$_SERVER['SCRIPT_NAME'] , 'modules' ) ) {
1047			// zx 2004/12/13 misc.php debug (file check)
1048			if( substr( @$_SERVER['SCRIPT_NAME'] , -8 ) == 'misc.php' && ( $_GET['type'] == 'debug' || $_POST['type'] == 'debug' ) && ! preg_match( '/^dummy_[0-9]+\.html$/' , $_GET['file'] ) ) {
1049				$this->output_log( 'misc debug' ) ;
1050				exit ;
1051			}
1052
1053			// zx 2004/12/13 misc.php smilies
1054			if( substr( @$_SERVER['SCRIPT_NAME'] , -8 ) == 'misc.php' && ( $_GET['type'] == 'smilies' || $_POST['type'] == 'smilies' ) && ! preg_match( '/^[0-9a-z_]*$/i' , $_GET['target'] ) ) {
1055				$this->output_log( 'misc smilies' ) ;
1056				exit ;
1057			}
1058
1059			// zx 2005/1/5 edituser.php avatarchoose
1060			if( substr( @$_SERVER['SCRIPT_NAME'] , -12 ) == 'edituser.php' && $_POST['op'] == 'avatarchoose' && strstr( $_POST['user_avatar'] , '..' ) ) {
1061				$this->output_log( 'edituser avatarchoose' ) ;
1062				exit ;
1063			}
1064		}
1065
1066		// zx 2005/1/4 findusers
1067		if( substr( @$_SERVER['SCRIPT_NAME'] , -24 ) == 'modules/system/admin.php' && ( $_GET['fct'] == 'findusers' || $_POST['fct'] == 'findusers' ) ) {
1068			foreach( $_POST as $key => $val ) {
1069				if( strstr( $key , "'" ) || strstr( $val , "'" ) ) {
1070					$this->output_log( 'findusers' ) ;
1071					exit ;
1072				}
1073			}
1074		}
1075
1076		// preview CSRF zx 2004/12/14
1077		// news submit.php
1078		if( substr( @$_SERVER['SCRIPT_NAME'] , -23 ) == 'modules/news/submit.php' && isset( $_POST['preview'] ) && strpos( @$_SERVER['HTTP_REFERER'] , XOOPS_URL.'/modules/news/submit.php' ) !== 0 ) {
1079			$HTTP_POST_VARS['nohtml'] = $_POST['nohtml'] = 1 ;
1080		}
1081		// news admin/index.php
1082		if( substr( @$_SERVER['SCRIPT_NAME'] , -28 ) == 'modules/news/admin/index.php' && ( $_POST['op'] == 'preview' || $_GET['op'] == 'preview' ) && strpos( @$_SERVER['HTTP_REFERER'] , XOOPS_URL.'/modules/news/admin/index.php' ) !== 0 ) {
1083			$HTTP_POST_VARS['nohtml'] = $_POST['nohtml'] = 1 ;
1084		}
1085		// comment comment_post.php
1086		if( isset( $_POST['com_dopreview'] ) && ! strstr( substr( @$_SERVER['HTTP_REFERER'] , -16 ) , 'comment_post.php' ) ) {
1087			$HTTP_POST_VARS['dohtml'] = $_POST['dohtml'] = 0 ;
1088		}
1089		// disable preview of system's blocksadmin
1090		if( substr( @$_SERVER['SCRIPT_NAME'] , -24 ) == 'modules/system/admin.php' && ( $_GET['fct'] == 'blocksadmin' || $_POST['fct'] == 'blocksadmin') && isset( $_POST['previewblock'] ) /* && strpos( $_SERVER['HTTP_REFERER'] , XOOPS_URL.'/modules/system/admin.php' ) !== 0 */ ) {
1091			die( "Danger! don't use this preview. Use 'altsys module' instead.(by Protector)" ) ;
1092		}
1093		// tpl preview
1094		if( substr( @$_SERVER['SCRIPT_NAME'] , -24 ) == 'modules/system/admin.php' && ( $_GET['fct'] == 'tplsets' || $_POST['fct'] == 'tplsets') ) {
1095			if( $_POST['op'] == 'previewpopup' || $_GET['op'] == 'previewpopup' || isset( $_POST['previewtpl'] ) ) {
1096				die( "Danger! don't use this preview.(by Protector)" ) ;
1097			}
1098		}
1099
1100	}
1101
1102
1103	// restore reporting level
1104	error_reporting( $error_reporting_level ) ;
1105}
1106
1107
1108function call_filter( $type , $dying_message = '' )
1109{
1110	require_once dirname(__FILE__).'/ProtectorFilter.php' ;
1111	$filter_handler =& ProtectorFilterHandler::getInstance() ;
1112	$ret = $filter_handler->execute( $type ) ;
1113	if( $ret == false && $dying_message ) {
1114		die( $dying_message ) ;
1115	}
1116
1117	return $ret ;
1118}
1119
1120
1121
1122}
1123?>