#!/usr/bin/php-cgi
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Origin: *");
/*
SMSGLOBAL Firewall API (REDPORT VERSION)
Author: Jose Mari Reyes

Date Completed:
version 1: 
	09-23-2017 REDPORT
	12-05-2017 FIX IP RULES		
	06-12-2018 SPECIFIC CREW NETWORK BLOCK ALLOW ONLY
	06-14-2018 MINOR FIX ON PORT 80 DELEGATE_OUTPUT
	06-19-2018 MODIFIED CODES FOR THE PORT 80.  BLOCKING PORT 3128 INSTEAD
	07-03-2018 FIX ON THE ISSUE OF PORT 80 AND 8080 CONDITION PREG_MATCH	
	07-30-2018 MORE FIX ON 80 AND 8080 WECHAT MODS
	11-08-2018 DEFAULT RULE FOR ALLOW ALL TO FIX REDIRECTION ISSUE,  NEW FUNCTION CONVERT TO BROADCAST ADDRESS
	11/21/2018 ADDITIONAL FLAG -w ON THE IPTABLES
	01/27/2020 RENAMED FROM CFW.REDPORT TO CFW.  
	
*CFW HAS BEEN REPLACED BY CREWCOMM ADVANCE FIREWALL ACFW
--------------------------------------------------------	

NOTE: MAKE SURE the FIREWALL_FILE and D_PREVSTATE_FILE are present at their respective directory
      The FIREWALL_FILE must have executable permission and the D_PREVSTATE_FILE has Read Write permission


MANUAL:

	cfw?<function>=<A|B><args>|<alias>
	
	function are:	
	
		filter   -  this is the one that accept argument and turn into command
		query    -  returns back the whole argument
		default	 -  reset the firewall

	
	args: Semicollon separated argumants 
	
		A - Allow All
		B - Block All
			
		T<port>  - TCP <port number>
		U<port>  - UDP <port number>
		I<addr>	 - IP <address>
		
	alias:  Field to identify each argument, comma separated
	
	Example: 
	
	1.  Allow All Block IP 203.192.132.1 and TCP Port Number 3306 (Mysql)
		
			cfw?filter=A;I203.192.132.1;T3306|BlockIP,MySQL	
	
	2.  Block All  Allow all IP in the network 222.145.165.0 and Allow HTTP
	
		    cfw?filter=B;I222.145.165.0/24;T80|AllowIP,HTTP
			
*/
define('FIREWALL_FILE', "/etc/smsg/firesmsg");
define("D_PREVSTATE_FILE", "/etc/smsg/firesmsg_prevstate");
 
$net = get_tun0_ip_net();
 
//---- BLOCK ALL ----
$tmpI  = "\niptables -w -I delegate_forward -s $net -j DROP";	//drop all 
$tmpI .= "\niptables -w -I delegate_output -p tcp --sport 3128 -j DROP"; // drop port 80. replaces all the codes above 6-19-2018
$tmpI .= "\niptables -w -I delegate_output -p udp --sport 3128 -j DROP"; // drop port 80. replaces all the codes above 6-19-2018

define("I_BLOCK_ALL", $tmpI);

//---- ALLOW ALL ----
$tmpA  = "iptables -w -I delegate_forward -s $net -j DROP\n";
$tmpA .= "iptables -w -I delegate_forward -s $net -p tcp --match multiport --dport 1:20000 -j ACCEPT\n";
$tmpA .= "iptables -w -I delegate_forward -s $net -p udp --match multiport --dport 1:20000 -j ACCEPT\n";

define("I_ALLOW_ALL", $tmpA);
define("I_BLOCK_TCP_HTTP", "iptables -w -I delegate_output -p tcp --sport 3128 -j DROP\n");
define("I_UNBLOCK_TCP_HTTP", "iptables -w -D delegate_output -p tcp --sport 3128 -j DROP\n");
define("I_BLOCK_UDP_HTTP", "iptables -w -I delegate_output -p udp --sport 3128 -j DROP\n");
define("I_UNBLOCK_UDP_HTTP", "iptables -w -D delegate_output -p udp --sport 3128 -j DROP\n");




$tmpD  = "\niptables -D delegate_forward -j DROP";
define("D_BLOCK_ALL", $tmpD);

define("TCP", "~T -p tcp --dport ");
define("UDP", "~U -p udp --dport ");
define("IP", "~P -s ");

define("COMMAND_IP", "iptables -w -I delegate_forward -s $net ");
define("COMMAND_DP", "iptables -w -D INPUT ");
define("COMMAND_I", "iptables -w -I delegate_forward -s $net ");
define("COMMAND_D", "iptables -w -D delegate_forward -s $net ");
define("JUMP_A", "-j ACCEPT");
define("JUMP_B", "-j DROP");


 

if (isset($_REQUEST['query']) == true)
{ 
	get_firewall_rules();  //get current setting
}

if (isset($_REQUEST['default']) == true)
{
	file_put_contents($FIREWALL_FILE, " "); //reset to nothing
	exit;
}

if (isset($_REQUEST['filter']) == false){ echo "0"; exit; }




 
$filter = $_REQUEST['filter'];
$cmd	= $filter;
$filter = explode("|", $filter); //separate the command from the alias
$filter = strtoupper($filter[0]);
$filter = trim($filter, ";");
$filter = str_replace(" ", '', $filter);
$filter = explode(";", $filter);

    //default allow all
	
	$i 			= 0;
	$RULES_I  	= "";
	$RULES_D  	= "";
	$target   	= JUMP_B;
	$HEAD_I 	= "";
	$HEAD_D		= "";
	$sw 		= 0;
	
	
	while ($i < count($filter))
 	{
		
		if ($filter[$i] == 'B' || $filter[$i] == 'A'){ 
			$HEAD_I = ($filter[$i] == 'B') ? I_BLOCK_ALL : I_ALLOW_ALL;
			//$HEAD_D = ($filter[$i] == 'B') ? D_BLOCK_ALL : "";  
			$target = ($filter[$i] == 'B') ? JUMP_A : JUMP_B;
			$sw = ($filter[$i] == 'B') ? 1 : 0;
			
			
		}else {
					
			$patterns = array ('/(T|t)/', '/(U|u)/', '/(I|i)/');
			$replace = array (TCP, UDP, IP);
			$DPORT = preg_replace($patterns, $replace, $filter[$i]);
			
			
			if (check_port_rules_if_valid($DPORT) == true)
			{
					$ret = ident_args($DPORT);
					
					$temp = explode(" ", $DPORT);
					echo 'DPORT: ' . $DPORT;	
					switch($ret)
					{
						case 0:
							//$RULES_D .= str_replace("~T", COMMAND_D, $DPORT) . " " . $target . "\n";
							//if (strpos($DPORT, "80") !== false)
							//if (preg_match('/[80]{2}/', $DPORT) == true)
							if (in_array("80", $temp) == true)		
							{ 	
								$tmpr  = ($sw == 1) ? I_UNBLOCK_TCP_HTTP :  I_BLOCK_TCP_HTTP;
							}
							else
							{       
								$tmpr = str_replace("~T", COMMAND_I, $DPORT) . " " . $target . "\n";
								//$tmpr .= str_replace("--dport", "--sport", $tmpr);
							}
							
							$RULES_I .= $tmpr;
							break;
								
						case 1:
							//if (strpos($DPORT, "80") !== false)
							//if (preg_match('/^80$/', $DPORT) == true)
							if (in_array("80", $temp) == true)
							{ 	
								$tmpr = ($sw == 1) ? I_UNBLOCK_UDP_HTTP :  I_BLOCK_UDP_HTTP;
							}
							else
							{
								$tmpr = str_replace("~U", COMMAND_I, $DPORT) . " " . $target . "\n";
								//$tmpr .= str_replace("--dport", "--sport", $tmpr);
							}
							
							$RULES_I .= $tmpr;
							break;
							
						case 2:
							echo "COMMAND_IP:" . COMMAND_IP;	
							echo "DPORT: " . $DPORT;
							$DPORT = str_replace("-s","-d",$DPORT);
							$tmpr = str_replace("~P", COMMAND_IP, $DPORT) . " " . $target . "\n";
						    	/*$tmpr .= str_replace("-s", "-d", $tmpr);*/	
							$RULES_I .= $tmpr;
							break;
					}
					
					
			}
		}
		 
		$i++;
	}
    
	
	
	//echo "<pre>===== FILE PREV ====\n";
	execute_remove_previous_rules();
	//echo "\n===========</pre>";
	 
	
	$rules_insert = "$HEAD_I\n$RULES_I";
	$rules_insert .= ($sw == 1) ? exemptions('I') : "";
	
	//$rules_delete = "$HEAD_D\n$RULES_D";
	//$rules_delete .= ($sw == 1) ? exemptions('D') : "";
	
	$FW_RULES = "#$cmd\n$rules_delete$rules_insert";
	
	
	//echo "<pre>$FW_RULES</pre>";
	

	$cmd = "echo \"$FW_RULES\" > " . FIREWALL_FILE;
	execute_shell($cmd);
	
	
	file_put_contents(D_PREVSTATE_FILE, $rules_delete);
	
	echo "1";




function ident_args($filter)
{
	if (strpos($filter, "~T") !== false) return 0;
	if (strpos($filter, "~U") !== false) return 1;
	if (strpos($filter, "~P") !== false) return 2;
}


/*Shell Execute the Previous Command Before the Change*/
function execute_remove_previous_rules()
{
	$prev_rules = @file_get_contents(D_PREVSTATE_FILE);
	if ($prev_rules === false) return;
	
	$prev_rules = explode("\n", $prev_rules);
	for ($i = 0; $i < count($prev_rules); $i++)
	{
		if (strlen($prev_rules[$i]) > 0) 
		{
	   		//echo "execute: " . $prev_rules[$i] . "\n";
		    execute_shell($prev_rules[$i]);
		}
	}
	
}


function execute_shell($cmd)
{
	//echo "<pre>$cmd\n<pre>";
	//file_put_contents(FIREWALL_FILE, $cmd);
	shell_exec($cmd);
}



function exemptions($mode = "I")
{
	$net = get_tun0_ip_net();
	
	$exemp = "";
	
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --dport 3129 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --dport 3128 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --dport 10990 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --dport 12010 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --dport 22 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --dport 22 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --dport 1812 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --dport 1813 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --dport 1814 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --dport 123 -j ACCEPT\n";

	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --sport 3129 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --sport 3128 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --sport 10990 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --sport 12010 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p tcp --sport 22 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --sport 22 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --sport 1812 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --sport 1813 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --sport 1814 -j ACCEPT\n";
	$exemp .= "iptables -w -I delegate_forward -s $net -p udp --sport 123 -j ACCEPT\n";

	$exemp .= "iptables -w -I delegate_forward -d 240.0.0.0/4 -j DROP\n";
	
	return $exemp;
}



function check_port_rules_if_valid($rules)
{
$RESERVED = array("53", "22", "90", "3990", "10990", "3128", "3129", "3442", "1812", "1813", "12010");

	$STACK = explode(" ", $rules);
	for ($i = 0; $i < count($RESERVED); $i++)
	{
		if (in_array($RESERVED[$i], $STACK) == true) return false;
	}
		
	return true;
}



function get_firewall_rules()
{
//global $FIREWALL_FILE;

	$IN = file_get_contents(FIREWALL_FILE);
	
	if (strlen($IN) < 0) { echo 0; exit(); }
	
	$IN = explode("\n", $IN); 
	$str = str_replace("#", '', $IN[0]);
	echo $str;
	exit;

}


function get_tun0_ip_net()
{
	$ip  = "";
	$net = "";
	
	$ip = shell_exec("ifconfig tun0 | awk '/inet addr:/ { sub(/addr:/, \"\", $2); print $2 }'");
	
	$ip = explode('.', $ip);
	
	$net = $ip[0] . "." . $ip[1] . "." . $ip[2] . ".0/24";

	return $net;	
}




/*
function check_port_if_http($rules)
{
$RESERVED = array("80", "12025");

	$STACK = explode(" ", $rules);
	for ($i = 0; $i < count($RESERVED); $i++)
	{
		if (in_array($RESERVED[$i], $STACK) == true) return true; 
	}
		
	return false;
}
*/


	
//iptables -A INPUT -s IP-ADDRESS -j DROP
/*
function block_allow_12025_proxy($target)
{
	$ip = get_proxy_ip();
	
	$rule_i = ""; $rule_d = "";
	
	for ($i = 0; $i < count($ip); $i++)
	{
		$ipv = $ip[$i];
		$rule_d .= "iptables -D INPUT -s $ipv " . $target . "\n";
		$rule_i .= "iptables -w -I INPUT -s $ipv " . $target . "\n";
	}
	
	return "$rule_d:$rule_i";
}
*/

/*function that gets the proxy ip addresses*/
/*
function get_proxy_ip()
{

  $cfg = file_get_contents(INTERNAL_PROXY_CFG);
  $ip = array();
  $counter = 0;
  
  if ($cfg != false)
  {
  		$cfg = explode("\n", $cfg);
		for ($i = 0; $i < count($cfg); $i++)
		{
		
			$pos = strpos($cfg[$i], "cache_peer");
			if ($pos !== false){
			
				$d = explode(" ", $cfg[$i]);
				$key = array_search("cache_peer", $d);
				$ip[$counter] = $d[($key+1)];
				
				$counter++;	
			}
			
			if ($i > 200) break;
		}
  }
  
  return $ip;
}
*/  	
?>

 
