#!/usr/bin/php-cgi
<?php
// header('Access-Control-Allow-Origin: *');
/********************************************************************************************

BW DNS FILTER
CREATED BY JOSE MARI REYES 

History:

08-15-2017	Version 1.0
09-24-2017	REDPORT
02-06-2018	Additional codes implementing TUN0 ip modification to address field of dnsmasq.conf
			overriding BLOCK_IP
02-08-2018	Change the reading of get_dns from uci to the /etc/smsg/dns file
02-12-2018      Change the reading of get_dns with fields, Change block ip from 127.0.0.1 to 240.0.0.1
02-14-2018	Returned back to 02-06-2018 mods
02-15-2018	Fix BLOCKIP additional variable $BLOCKIP and define BLOCK_IP
02-21-2018	LINKSYS AND REDPORT
03-01-2018	Fix Block IP  Get tun0 for Redport and 10.0.0.1 for Linksys
03-06-2018	Fix Linksys getlan API (tun0)
03-15-2017	Fix Linksys and Redport Blocking IP interoperability 
08-30-2018	Returned Dns server IP changed to 240.0.0.1  There is a problem with 10.1.5.1
01-27-2020	REMOVED ALL REFERRENCE FOR LINKSYS SUPPORT.  CODE IS PURE REDPORT ONLY


MANUAL:

BW DNS FILTER

	Allow and Block ALL DNS


	Setting Values:
	
		A - Allow All DNS (resolv all)
		B - Block All DNS
	


WHITE LIST
==========

	
1.	Add URL to White List
	==========================
	
	http://192.168.32.1/cgi-bin/dnsfilter?whitelist_allow=facebook.com



	
2.	Read All Whiteisted URL
	================================
	
	http://192.168.32.1/cgi-bin/dnsfilter?whitelist_read
	
	The return value is newline delimited result.  
		
	Return:

		cnn.com
		google.com
	


3.	Remove An Entry in the Whitelist
	================================
	
	http://192.168.32.1/cgi-bin/dnsfilter?whitelist_remove=cnn.com
	
	
	
	
BLACKLIST
=========	
	
1.	Add URL to Blacklist
	==========================
	
	http://192.168.32.1/cgi-bin/dnsfilter?blacklist_allow=facebook.com

	
2.	Read All Blacklisted URL
	================================
	
	http://192.168.32.1/cgi-bin/dnsfilter?blacklist_read
	
	The return value is newline delimited result.
		
	Return:

		xxx.com
		cashcash.com
	


	Remove An Entry in the Blacklist
	================================
	
	http://192.168.32.1/cgi-bin/dnsfilter?blacklist_removexxx.com
	
	
	

DNS FILTERING
=============	
	
	
	Set Block or Allow All DNS Resolution
	=====================================
	
	To Block All Resolution
	
	http://192.168.32.1/cgi-bin/dnsfilter?setallowblock=B
	
	To Allow All Resolution
	
	http://192.168.32.1/cgi-bin/dnsfilter?setallowblock=A
	
	
	Read DNS Filter Setting
	=======================
	
	http://192.168.32.1/cgi-bin/dnsfilter?read_dnsfilter

	This will return the current DNS filter setting
	
	If Allow all, API returns the setting along with BlackListed URL
	if Block all, API returns the setting along with WhiteListed URL
	
	Return:

		-- If Allow ALL
		
		A
		xxx.com
		porn.com
		
		-- If Block All
		
		B
		cnn.com
		facebook.com




	Refresh DNS 
     	===========

	http://192.168.32.1/cgi-bin/dnsfilter?dnsfilter_update

	This will update the DNS1 and DNS2 when this settings are changed using autodns API


	Reload
	======

	http://192.168.32.1/cgi-bin/dnsfilter?reload

	This will restart dnsmasq to reload all commands


---------------------------------------------------------------------------------------------
********************************************************************************************/
error_reporting(0);
define("DNS1", "8.8.8.8");
define("DNS2", "8.8.4.4");
define("RP_BLOCK_IP", "240.0.0.1");
define("LS_BLOCK_IP", "10.0.0.1");
define("CONFIG", "/etc/dnsmasq.conf");
define("DNS_DEFAULT", "no-resolv\n");
define("BWLIST", "/etc/smsg/bwlist");
define("FILTER", "/etc/smsg/dnsfilterset");
define("DNSFILE", "/etc/smsg/dns");

echo "<pre>";

	if (isset($_REQUEST['dnsfilter_update']) == true)
	{
		set_permission('W');
		compile();
		set_permission('R');
	}
	
	
	
	if (isset($_REQUEST['showdns']) == true)
	{
		$v = get_dns();
		print_r($v);
	}



	if (isset($_REQUEST['whitelist_read']) == true)
	{
		echo read_bwlist("W");
	}
	
	
	if (isset($_REQUEST['whitelist_allow']) == true)
	{
		$url  = $_REQUEST['whitelist_allow'];
		if (strlen($url) < 1) echo "-1";
		else 
			add_bwlist("W", $url);
		
	
	}



	if (isset($_REQUEST['whitelist_remove']) == true)
	{
		$url  = $_REQUEST['whitelist_remove'];
		if (strlen($url) < 1) echo "-1";
		else  
			remove_bwlist("W", $url);
	
	}

	if (isset($_REQUEST['setallowblock']) == true)
	{
		$set = $_REQUEST['setallowblock'];
		if (strlen($set) < 1) echo "-1";
		else  	
			set_dnsfilter($set);
	
	}


	if (isset($_REQUEST['read_dnsfilter']) == true)
	{
		echo read_dnsfilter();
	}


	if (isset($_REQUEST['blacklist_read']) == true)
	{
		echo read_bwlist("B");
	}


	if (isset($_REQUEST['blacklist_allow']) == true)
	{
		$url  = $_REQUEST['blacklist_allow'];
		if (strlen($url) < 1) echo "-1";
		else 
			add_bwlist("B", $url);
		
	}



	if (isset($_REQUEST['blacklist_remove']) == true)
	{
		$url  = $_REQUEST['blacklist_remove'];
		if (strlen($url) < 1) echo "-1";
		else  
			remove_bwlist("B", $url);
	
	}
	
	
	
 	if (isset($_REQUEST['reload']) == true)
	{
		reload_dnsmasq();
	}


      	if (isset($_REQUEST['getlan']) == true)
	{
		echo "<pre>" . get_tun0_ip(1);
	}




function compile()
{
$dns1 = DNS1;
$dns2 = DNS2;
	
	$DNS = get_dns();
	$dns1 = $DNS['DNS1'];
	$dns2 = $DNS['DNS2'];
	
	$BLOCKIP = trim(get_tun0_ip_ex());	
		
	$fp = file_get_contents(BWLIST);
	$v = explode("\n", $fp);
	
	//print_r($v);
	$mode = -1;
	$data = DNS_DEFAULT;	
    $data.= "conf-file=/www/captivedomains.conf\n";//Added by tom Feb 7,2020
	$filter = file_get_contents(FILTER); //get set filter
	$filter = trim($filter);
	
	$ADDR_BLOCK_IP = ident_block_ip();
 

	if ($filter == 'A') { $data .= "server=/#/" . $dns1 . "\n";  $mode = 1; }else{ $data .= "address=/#/" . $ADDR_BLOCK_IP . "\n"; $mode = 0; }
		
		for ($i = 0; $i < count($v); $i++)
		{
			$tmp = explode("|", $v[$i]);
				
			if (count($tmp) > 1)
			{	
				if ($mode == 1)
				{	
					if ($tmp[0] == 'B'){
						$data .= "server=/" . $tmp[1] . "/" . $BLOCKIP . "\n";
						//$data .= "server=/" . $tmp[1] . "/" . $BLOCKIP . "\n";
					}					
				}
				elseif ($mode == 0)
				{
					if ($tmp[0] == 'W'){
						$data .= "server=/" . $tmp[1] . "/" . $dns1 . "\n";
						$data .= "server=/" . $tmp[1] . "/" . $dns2 . "\n";
					}
				}
			}
			
		}
	
	
	//echo $data;
	file_put_contents(CONFIG, $data);

	//Override BLOCK_IP
	//$iplisten = get_tun0_ip();	
	//$cmd = "sed -i -e \"s/address=\/\#\/*.*.*.*/address=\/\#\/$iplisten/\" /etc/dnsmasq.conf";
        //exec($cmd);
}


function ident_block_ip()
{
	/*
	include_once("sysinfo");

        $inf = sysinfo();

	return ($inf == LS) ? LS_BLOCK_IP : RP_BLOCK_IP; 	
    */
	
	return RP_BLOCK_IP; 	
}


//if mode != 0 it queries the tun0, only for linksys
function get_tun0_ip($mode = 0)
{
	/*
	include_once("sysinfo");
	
	$inf = sysinfo();

	
	if ($inf == LS) //linksys
	{
		if ($mode == 0) return LS_BLOCK_IP;
	}
	else
	{
		//return RP_BLOCK_IP;

		$ip = shell_exec("ifconfig tun0 | awk '/inet addr:/ { sub(/addr:/, \"\", $2); print $2 }'");
		return $ip;
	}
	*/

	$ip = shell_exec("ifconfig tun0 | awk '/inet addr:/ { sub(/addr:/, \"\", $2); print $2 }'");
	return $ip;
	
}


function get_tun0_ip_ex($mode = 0)
{
	/*
        include_once("sysinfo");

        $inf = sysinfo();


        if ($inf == LS) //linksys
        {
                if ($mode == 0) return LS_BLOCK_IP;
        }
        else
        {
                return RP_BLOCK_IP;

                //$ip = shell_exec("ifconfig tun0 | awk '/inet addr:/ { sub(/addr:/, \"\", $2); print $2 }'");
                //return $ip;
        }
	*/
	
	return RP_BLOCK_IP;
}




function read_bwlist($type)
{
	$fp = file_get_contents(BWLIST);
	$v = explode("\n", $fp);
	
	//print_r($v);
	$mode = -1;
	$data = "";
	
		for ($i = 0; $i < count($v); $i++)
		{
			$tmp = explode("|", $v[$i]);
				
			if (count($tmp) > 1)
			{	
				if ($type == "B")
				{	
					if ($tmp[0] == 'B'){
						$data .= $tmp[1] . "\n";
					}					
				}
				elseif ($type == "W")
				{
					if ($tmp[0] == 'W'){
						$data .= $tmp[1] . "\n";
					}
				}
			}
			
		}
	
	//echo $data;
	return $data;
	
}



function set_dnsfilter($type)
{
	$data = "";
	
	if ($type == 'A') $data = "A"; else $data = "B";
	file_put_contents(FILTER, $data);
	
}


function read_dnsfilter()
{
	
	$fp = file_get_contents(BWLIST);
	$v = explode("\n", $fp);
	
	//print_r($v);
	$mode = -1;
	
	$filter = file_get_contents(FILTER); //get set filter
	$filter = trim($filter);
	if ($filter == 'A') { $data = "A\n";  $mode = 1; } else { $data = "B\n"; $mode = 0; }
		
		for ($i = 0; $i < count($v); $i++)
		{
			$tmp = explode("|", $v[$i]);
				
			if (count($tmp) > 1)
			{	
				if ($mode == 1)
				{	
					if ($tmp[0] == 'B'){
						$data .= $tmp[1] . "\n";
					}					
				}
				elseif ($mode == 0)
				{
					if ($tmp[0] == 'W'){
						$data .= $tmp[1] . "\n";
					}
				}
			}
			
		}
	
	
	//echo $data;
	return $data;
		
}


function add_bwlist($type, $url)
{
	$fp = file_get_contents(BWLIST);
	$v = explode("\n", $fp);
	$data = "";
	for ($i = 0; $i < count($v) ; $i++)
	{
		$tmp = trim($v[$i]);
		if (strlen($tmp) > 1) $data .= "$tmp\n";
	}
	
	if ($type == 'W') $data .= "W|$url\n";
	if ($type == 'B') $data .= "B|$url\n";
	
    file_put_contents(BWLIST, $data);
	compile();
}




function remove_bwlist($type, $url)
{

	$fp = file_get_contents(BWLIST);
	$v = explode("\n", $fp);
	$data = "";
	$item = "$type|$url";
	//echo ">>>$item<<<";
	for ($i = 0; $i < count($v) ; $i++)
	{
		$tmp = trim($v[$i]);
		//echo "[$tmp]\n";
		if (strcmp($tmp, $item) == 0) 
			$tmp = ""; //do nothing
		else
			if (strlen($tmp) > 1) $data .= "$tmp\n";
	}
	
    	file_put_contents(BWLIST, $data);
	compile();

}




function set_permission($cmd)
{
	if ($cmd == 'W') $ex = "chmod ugo+w " . CONFIG;
	if ($cmd == 'R') $ex = "chmod ugo-w " . CONFIG;

	exec($ex);
}


function get_dns()
{
	$dns1 = get_dns_value("DNS1");
	$dns2 = get_dns_value("DNS2");
	
	if (strlen($dns1) < 1) $dns1 = DNS1;
	if (strlen($dns2) < 1) $dns2 = DNS2;
	
	
	$array = array(
    	"DNS1" => $dns1,
    	"DNS2" => $dns2,
	);	

	return $array;
}



function get_dns_value($dns)
{

	$fstr = file_get_contents(DNSFILE);
	
	$v = explode("\n", $fstr);
	
	$key = $dns;
	
	$dns = "";
	//print_r($v);
	for ($i = 0; $i < count($v); $i++)
	{
		if (($pos = strpos($v[$i], $key)) !== false)
		{
			//echo "orig:" . $v[$i] . "\n";
			$tok = explode("=", $v[$i]);
			//print_r($tok);
			
			for ($ii = 0; $ii < count($tok); $ii++)
			{
				if (strcmp($tok[$ii], $key) == 0){
				 	$dns = $tok[$ii+1];
					
					break; 
				}	
			}
			
		}
	}
	
	return trim($dns, '"');
}


function reload_dnsmasq()
{
	$exec = "/etc/init.d/dnsmasq restart";
	exec($exec, $x);

}



function strloc($haystack, $needle)
{
	if ( preg_match("~\b$needle\b~",$haystack) )
  		return true;
	else
  		return false;
  
}


?> 
