<?php
class Ban_Control {
/* global varibales */
protected $db_host = "";
// MySQL Data Base user name
protected $db_user = "";
// MySQL Data Base Password
protected $db_password = "";
// MySQL Data Base Name
protected $db_name = "";
public $Date_String = 'F j, Y, g:i a'; // date string for a nice date display
public $Create_Link = 'index.php?create';
public $List_Link = 'index.php?list';
public $Info_Link = 'index.php?info=';
public $Remove_Link = 'index.php?remove=';
public $Update_Link = 'index.php?update=';
private $html_die_msg = '<html><head><title>Ip ban for [ip]</title></head><body>
<div align="center" style="padding-top:10%">
<h1><font color="red">Banned Notice</font></h1>
Your IP: <font color="red"><b>[ip]</b></font> was banned on <font color="red"><b>[add_date]</b></font><br />
You have made <font color="red"><b>[attempts]</b></font> attempts to visit.<br />
You have [days_left] days left<br/>
Reason for your ban:<br />
[reason]</div></body></html>';
private $proxy_headers = array(
'HTTP_VIA',
'HTTP_X_FORWARDED_FOR',
'HTTP_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED',
'HTTP_CLIENT_IP',
'HTTP_FORWARDED_FOR_IP',
'VIA',
'X_FORWARDED_FOR',
'FORWARDED_FOR',
'X_FORWARDED',
'FORWARDED',
'CLIENT_IP',
'FORWARDED_FOR_IP',
'HTTP_PROXY_CONNECTION');
/* DO NOT EDIT PAST THIS POINT UNLESS YOU KNOW WHAT YOUR DOING */
// start of public functions
//
// Main checking functions
// Start the main function.
// returns if a ban is true or not.
public function Ban($banarray){
$this->Details();
if($banarray[proxy_check]==1){
$this->Proxy_Check();
}
if($banarray[robot_check]==1){
$this->Robot_Check();
}
if($banarray[ban_check]==1){
$this->Host_Check();
$this->Ip_Check();
}
return;
}
// start of private functions
//
// Grab Details
// Obtains and stores in varibles the users remote data.
// returns ip, host, ref, url, agent to varibles.
private function Details(){
$this->new_ip = $_SERVER['REMOTE_ADDR'];
$this->new_host = gethostbyaddr($_SERVER['REMOTE_ADDR']);
$this->new_ref = $_SERVER['HTTP_REFERER'];
$this->new_url = $_SERVER['REQUEST_URI'];
$this->new_agent = $_SERVER['HTTP_USER_AGENT'];
return;
}
// Proxy checking
// checks the users agent and proxy_headers array for possible proxy.
private function Proxy_Check(){
if(isset($_SERVER['HTTP_USER_AGENT'])==''){
die("Proxy servers not allowed.");
}
foreach($this->proxy_headers as $x){
if(isset($_SERVER[$x])){
die("You are using a proxy.");
exit;
}
}
return;
}
// Robot Trap
// logs a robots details for instant site ban.
private function Robot_Check(){
$res = mysql_query("SELECT * FROM bans WHERE ip = '$this->new_ip'",$this->GetMyConnection())or die('Error : ' . mysql_error());
if($row=mysql_num_rows($res)==0){
$now = date("$this->Date_String");
mysql_query("INSERT INTO bans (`ip`, `host`, `last_ref`, `last_url`, `last_agent`, `reason`, `add_date`, `add_date2`, `attempts`, `last_attempt`, `expiry`)
VALUES('$this->new_ip','$this->new_host','$this->new_ref','$this->new_url','$this->new_agent','Bot detection system',NOW(),'$now','1',NOW(),0)",$this->GetMyConnection())or die('Error : ' . mysql_error());
}
return;
}
// host checking
// attempts to match the users host name with a db entry.
private function Host_Check(){
$res = mysql_query("SELECT * FROM bans WHERE host = '$this->new_host'",$this->GetMyConnection())or die('Error : ' . mysql_error());
if(mysql_num_rows($res)==1) {
$this->Results($res);
$this->Expired();
$this->Update();
$this->Get_Hosts_Ips($this->new_host);
$this->Banned();
}
return;
}
// ip checking
// attempts to match the users ip address with a db entry.
private function Ip_Check(){
$res = mysql_query("SELECT * FROM bans WHERE ip LIKE '$this->new_ip' or ip = '$this->new_ip'",$this->GetMyConnection())or die('Error : ' . mysql_error());
if(mysql_num_rows($res)==1) {
$this->Results($res);
$this->Expired();
$this->Update();
$this->Get_Hosts_Ips($this->new_host);
$this->Banned();
}
return;
}
// Grab Details
// Obtains the users details if it matchs.
private function Results($res){
while($row=mysql_fetch_array($res)) {
$this->banned_id = $row[id];
$this->banned_ip = $row[ip];
$this->banned_ip_lh = $row[host];
$this->banned_ip_lr = $row[last_ref];
$this->banned_ip_lu = $row[last_url];
$this->banned_ip_la = $row[last_agent];
$this->banned_ip_lad = $row[last_attempt_date];
$this->banned_ip_lat = $row[last_attempt_time];
$this->banned_ip_nice_add_date = $row[add_date2];
$this->banned_ip_add_date = $row[add_date];
$this->banned_ip_add_date2 = $row[add_date2];
$this->attempts = $row[attempts];
$this->banned_ip_reason = $row[reason];
$this->banned_expire = $row[expiry];
}
return;
}
// Expired
// provides a way of creating timed out bans.
// wipes the users ban.
private function Expired(){
$join_array = explode('-', $this->banned_ip_add_date);
$dif = mktime(date("G"),date("i"),date("s"),date("m"),date("d"),date("Y")) - mktime('00','00','00',$join_array[1],$join_array[2],$join_array[0]);
$years = floor($dif/365/60/60/24);
$months = floor($dif/60/60/24/7/4);
$weeks = floor($dif/60/60/24/7);
$days = floor($dif/60/60/24);
$hours = floor($dif/60/60);
$mins = floor($dif/60);
$this->banned_expire_days_left = $this->banned_expire - $days;
if($this->banned_expire>=1)
if($days>$this->banned_expire){
mysql_query("delete from bans where ip = '$this->banned_ip'",$this->GetMyConnection());
return true;
}
}
// Check bans
// Carrys out the final check.
// if banned match true it updates and rejects the user.
private function Banned(){
$this->Replace_Str();
$this->Reject();
return;
}
// Update users Attempts
// Attempts to match and update the users hit attempts.
private function Update(){
return mysql_query("UPDATE bans SET host ='$this->new_host', last_ref = '$this->new_ref', last_url = '$this->new_url', last_agent = '$this->new_agent', last_attempt = NOW(), attempts = attempts+1 WHERE ip = '$this->banned_ip'",$this->GetMyConnection())or die('Error : ' . mysql_error());
}
// Reject
// Rejects the user properly.
// Returns a 403 header status and a custom html die msg.
private function Reject(){
header('HTTP/1.1 403 Forbidden');
die($this->html_die_msg);
return;
}
// Replace String.
// Provides means of replacing the constants used in the ban die messages.
// returns a proper string for displaying.
private function Replace_Str(){
$this->html_die_msg = str_replace('[ip]',$this->banned_ip, $this->html_die_msg);
$this->html_die_msg = str_replace('[last_host]',$this->banned_ip_lh, $this->html_die_msg);
$this->html_die_msg = str_replace('[last_ref]',$this->banned_ip_lr, $this->html_die_msg);
$this->html_die_msg = str_replace('[last_url]',$this->banned_ip_lu, $this->html_die_msg);
$this->html_die_msg = str_replace('[last_agent]',$this->banned_ip_la, $this->html_die_msg);
$this->html_die_msg = str_replace('[last_date]',$this->banned_ip_lad, $this->html_die_msg);
$this->html_die_msg = str_replace('[last_time]',$this->banned_ip_lat, $this->html_die_msg);
$this->html_die_msg = str_replace('[add_time]',$this->banned_ip_add_time, $this->html_die_msg);
$this->html_die_msg = str_replace('[add_date]',$this->banned_ip_add_date2, $this->html_die_msg);
$this->html_die_msg = str_replace('[attempts]',$this->attempts, $this->html_die_msg);
$this->html_die_msg = str_replace('[reason]',$this->banned_ip_reason, $this->html_die_msg);
$this->html_die_msg = str_replace('[days_left]',$this->banned_expire_days_left, $this->html_die_msg);
}
// Validate Ips
// Checks with regexp weather an ip is real or fake.
// returns true or die.
private function Validate_Ip($ip){
if(preg_match("^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}^", $ip)){
return true;
}else{
return die('<h1>Please enter a valid IP</h1>');
}
}
// Robot Trap
// logs a robots details for instant site ban.
private function Extra($ip, $host){
$res = mysql_query("SELECT * FROM bans WHERE ip = '$ip'",$this->GetMyConnection())or die('Error : ' . mysql_error());
if(mysql_num_rows($res)==0){
$now = date("$this->Date_String");
mysql_query("INSERT INTO bans (`ip`, `host`, `reason`, `add_date`, `add_date2`, `attempts`, `last_attempt`, `expiry`)
VALUES('$ip','$host','Belongs to Host name $host',NOW(),'$now','0',NOW(),0)",$this->GetMyConnection())or die('Error : ' . mysql_error());
}else{
return false;
}
return true;
}
// Get Ip
// checks with php gethostbyname for a ip that belongs to a hostname.
// returns the ip addr
private function Get_Hosts_Ips($host){
$iplist = gethostbynamel($host);
if(is_array($iplist)){
foreach ($iplist as $num=>$ip){
$this->Extra($ip,$host);
}
}
return;
}
// Get Ip
// checks with php gethostbyname for a ip that belongs to a hostname.
// returns the ip addr
private function Get_Ip($host){
return gethostbyname($host);
}
// Get Hosts
// checks with php gethostbyaddr for hostname that belongs to a ip addr.
// returns the ip addr
private function Get_Host($ip){
return gethostbyaddr($ip);
}
// Duplicate date check
// checks if an ip or host is already added to the database
private function Duplicate_Check($col, $match){
$res = mysql_query("SELECT * FROM bans WHERE $col = '$match'",$this->GetMyConnection()) or die('Error : ' . mysql_error());
if(mysql_num_rows($res)==1){
return die('Your '.$col.' ['.$match.'] already matchs one in the database');
}
return true;
}
// empty strings alert
// checks if an form entered string is empty
// returns with a custom die message
private function Check_Empty($data){
if(!$data[ip] && !$data[host]){
die('<h1>Please enter a ip or host</h1>');
}elseif(!$data[reason]){
die('<h1>Please enter a Reason</h1>');
}
return;
}
// Ban destroy
// Destroy a ban if its no longer required.
// returns true if passed.
public function Ban_Destroy($data){
mysql_query("DELETE FROM bans WHERE id = '$data'",$this->GetMyConnection()) or die('Error : ' . mysql_error());
return true;
}
// Ban create
// Create new bans via the browser.
// returns true if passed.
public function Ban_Create($data){
if(is_array($data) && count($data) > 0){
$this->Check_Empty($data);
if(!empty($data[host])){
$data[ip] = $this->Get_Ip($data[host]);
$this->Duplicate_Check('host',$data[host]);
$nohost = true;
}
if(!empty($data[ip]) && $nohost==false){
$this->Validate_Ip($data[ip]);
$data[host] = $this->Get_Host($data[ip]);
$this->Duplicate_Check('ip',$data[ip]);
}
$data['add_date2'] = date("$this->Date_String");
$data['add_date'] = date("y-m-d");
foreach ($data as $k => $v ){ $data[$k] = "'".$v."'";}
mysql_query("INSERT INTO bans (`".implode('`, `', array_keys($data))."`) VALUES (".implode(", ", $data).")",$this->GetMyConnection());
$this->Get_Hosts_Ips($data[host]);
}else{
die('Create String not in array');
return false;
}
return true;
}
// Ban Update
// update a bans details.
// returns true if passed.
public function Ban_Update($data){
if(is_array($data) && count($data) > 0){
$i=1;
$query .= 'UPDATE bans SET ';
foreach ($data as $k => $v) {
$query .= "`".$k."` = '".$v."'".(($i++ < count($data)) ? ', ' : ' ');
}
$query .= "WHERE id = '$data[id]'";
mysql_query($query,$this->GetMyConnection())or die('Error : ' . mysql_error());
}else{
die('Update String not in array');
return false;
}
return true;
}
// Ban List
// List all current bans.
// returns the bans lists array.
public function Ban_List(){
$res = mysql_query("SELECT * FROM bans",$this->GetMyConnection()) or die('Error : ' . mysql_error());
if(mysql_num_rows($res)==0){
$output = 'No Bans, Please Add some';
}else{
while($row = mysql_fetch_array($res)){
$output .= '<br/> Ip: '.$row[ip].' | Hostname: '.$row[host].' <a href="'.$this->Update_Link.$row[id].'">Update</a> <a href="'.$this->Remove_Link.$row[id].'">delete</a> <a href="'.$this->Info_Link.$row[id].'"> Information</a>';
}
}
return $output;
}
// Ban Info
// Grab a single bans information.
// returns the bans information array.
public function Ban_Info($id, $row){
$res = mysql_query("SELECT * FROM bans WHERE id ='$id'",$this->GetMyConnection()) or die('Error : ' . mysql_error());
$list = mysql_fetch_array($res);
if($list[$row]=="")$list[$row]='N/A';
return $list[$row];
}
// ban update form
// displays a form filled with the current ids data
public function Ban_Update_Form($id){
$output = '<form method="post" action="'.$this->Update_Link.$this->Ban_Info($id,'id').'">
<br /><select size="1" name="expiry">
<option selected value="0">Never</option>
<option value="1">1 days</option>
<option value="2">2 days</option>
<option value="3">3 days</option>
<option value="4">4 days</option>
<option value="5">5 days</option>
<option value="6">6 days</option>
<option value="7">7 days</option>
<option value="8">8 days</option>
<option value="9">9 days</option>
<option value="10">10 days</option>
<option value="11">11 days</option>
<option value="12">12 days</option>
<option value="13">13 days</option>
<option value="14">14 days</option>
<option value="15">15 days</option>
<option value="16">16 days</option>
<option value="17">17 days</option>
<option value="18">18 days</option>
<option value="19">19 days</option>
<option value="20">20 days</option>
<option value="21">21 days</option>
<option value="22">22 days</option>
<option value="23">23 days</option>
<option value="24">24 days</option>
<option value="25">25 days</option>
<option value="26">26 days</option>
<option value="27">27 days</option>
<option value="28">28 days</option>
<option value="29">29 days</option>
<option value="30">30 days</option>
</select><label>Ban lenght</label>
<br /><input type="text" name="ip" size="20" maxlength="60" value="'.$this->Ban_Info($id,'ip').'"><label>Ip to ban</label>
<br /><input type="text" name="host" size="20" maxlength="60" value="'.$this->Ban_Info($id,'host').'"><label>Host name to ban</label>
<br /><textarea rows="3" name="reason" cols="22">'.$this->Ban_Info($id,'reason').'</textarea><label>Reason for ban</label>
<br /><input type="submit" value="Submit" name="edit">
</form>';
return $output;
}
// ban form
// allows a form to be easy created for ban adding
public function Ban_Create_Form(){
$output = '<form method="post" action="'.$this->Create_Link.'">
<br /><select size="1" name="expiry">
<option selected value="0">Never</option>
<option value="1">1 days</option>
<option value="2">2 days</option>
<option value="3">3 days</option>
<option value="4">4 days</option>
<option value="5">5 days</option>
<option value="6">6 days</option>
<option value="7">7 days</option>
<option value="8">8 days</option>
<option value="9">9 days</option>
<option value="10">10 days</option>
<option value="11">11 days</option>
<option value="12">12 days</option>
<option value="13">13 days</option>
<option value="14">14 days</option>
<option value="15">15 days</option>
<option value="16">16 days</option>
<option value="17">17 days</option>
<option value="18">18 days</option>
<option value="19">19 days</option>
<option value="20">20 days</option>
<option value="21">21 days</option>
<option value="22">22 days</option>
<option value="23">23 days</option>
<option value="24">24 days</option>
<option value="25">25 days</option>
<option value="26">26 days</option>
<option value="27">27 days</option>
<option value="28">28 days</option>
<option value="29">29 days</option>
<option value="30">30 days</option>
</select><label>Ban lenght</label>
<br /><input type="text" name="ip" size="20" maxlength="60"><label>Ip to ban</label>
<br /><input type="text" name="host" size="20" maxlength="60"><label>Host name to ban</label>
<br /><textarea rows="3" name="reason" cols="22"></textarea><label>Reason for ban</label>
<br /><input type="submit" value="Submit" name="add">
</form>';
return $output;
}
private function checkCon(){
if(!isset($this->g_link)){
$this->g_link = false;
}
return;
}
private function GetMyConnection(){
$this->checkCon();
if($this->g_link)
return $this->g_link;
$this->g_link = mysql_connect($this->db_host, $this->db_user, $this->db_password) or die('Could not connect to mysql server.' );
mysql_select_db($this->db_name, $this->g_link) or die('Could not select database.');
return $this->g_link;
}
private function CleanUpDB(){
$this->checkCon();
global $g_link;
if($g_link != false)
mysql_close($g_link);
$g_link = false;
}
//
// End of class
//
}
?>