<?php
#########################################################################################################
#  ip-blacklist-check-sample.php
#
#  Copyright (C) Softnik Technologies. All rights reserved.
#
#  Sample PHP script that checks the IP address of MX records against common DNSBL.
#  Remember to copy and or rename this file before making changes. This will protect your modifications 
#  from getting over-written. The best place to keep custom scripts is the 'lib/php/custom/' folder.
# 
#  The output will be saved to the notes_d column in the sub-domain table.
#
#  Before using this
#  -----------------
#  The script will require that you login if you have password protected the application. However this
#  will be a problem when running this script as a cronjob from a remote server. To fix this we 
#  use the 'CLI Authorization Key'. The 'CLI Authorization Key' is a unique string / password you set  
#  from the 'Application Settings > Authentication' tab.
#  After you have specified the key, use it in your cron entry as follows.
#
#  wget http://server/path/ip-blacklist-check.php?key=xxxxxx
#
#########################################################################################################

$dnsbl_lookup_array = [
"all.s5h.net", "b.barracudacentral.org", "bl.spamcop.net", "blacklist.woody.ch", "bogons.cymru.com", 
"cbl.abuseat.org", "cdl.anti-spam.org.cn", "combined.abuse.ch", "db.wpbl.info", "dnsbl-1.uceprotect.net", 
"dnsbl-2.uceprotect.net", "dnsbl-3.uceprotect.net", "dnsbl.anticaptcha.net", "dnsbl.cyberlogic.net", 
"dnsbl.dronebl.org", "dnsbl.inps.de", "dnsbl.sorbs.net", "drone.abuse.ch", 
"duinv.aupads.org", "dul.dnsbl.sorbs.net", "dyna.spamrats.com", "dynip.rothen.com", 
"exitnodes.tor.dnsbl.sectoor.de", "http.dnsbl.sorbs.net", "ips.backscatterer.org", 
"ix.dnsbl.manitu.net", "korea.services.net", "misc.dnsbl.sorbs.net", "noptr.spamrats.com", 
"orvedb.aupads.org", "pbl.spamhaus.org", "proxy.bl.gweep.ca", "psbl.surriel.com", 
"relays.bl.gweep.ca", "relays.nether.net", "sbl.spamhaus.org", "short.rbl.jp", 
"singular.ttk.pte.hu", "smtp.dnsbl.sorbs.net", "socks.dnsbl.sorbs.net", "spam.abuse.ch", 
"spam.dnsbl.anonmails.de", "spam.dnsbl.sorbs.net", "spam.spamrats.com", "spambot.bls.digibase.ca", 
"spamrbl.imp.ch", "spamsources.fabel.dk", "ubl.lashback.com", "ubl.unsubscore.com", "virus.rbl.jp", 
"web.dnsbl.sorbs.net", "wormrbl.imp.ch", "xbl.spamhaus.org", "z.mailspike.net", "zen.spamhaus.org", 
"zombie.dnsbl.sorbs.net", "bl.nszones.com", 
//"dnsbl.spfbl.net",
];

#########################################################################################################

# Please edit below if you move this script to a different folder.

require_once(dirname(__FILE__) . "/../basic.php");
require_once(dirname(__FILE__) . "/../config.check.php");
require_once(dirname(__FILE__) . "/../version.php");
require_once(dirname(__FILE__) . "/../pdo/dbinit.php");

#########################################################################################################
# Parse command line if running in CLI

if(is_cli())
	parse_str(implode('&', array_slice($argv, 1)), $_REQUEST);

#########################################################################################################

loginIfRequired(true); // Admin privileges required.

#########################################################################################################

$verbose        	= false;
$refresh_days   	= 30;
$domain_batch_size 	= 2;

if(isset($_REQUEST['v']))
	$verbose = true;
if(isset($_REQUEST['d']))
{
	$days = intval($_REQUEST['d']);
	if($days >= -1 && $days <= 365)
		$refresh_days = $days;
}
if(isset($_REQUEST['b']))
{
	$batch = intval($_REQUEST['b']);
	if($batch > 0 && $batch <= 100)
		$domain_batch_size = $batch;
}

#########################################################################################################

$pdo = init_db(false);
if($pdo === false)
{
	smartEcho("Unable to connect to database");
	exit;
}

$columns = $pdo->getAllColumnNames();
if($columns !== false)
{
	# date time column
	if(!in_array('ipbl_checked_at', $columns))
		$pdo->addDateTimeColumn('ipbl_checked_at');
	
	# Find the domains to lookup.
	$domain_names = "";
	$domain_array = array();

	$lookup_array = $pdo->getDomainsToLookup("ipbl_checked_at", $domain_batch_size, $refresh_days);
	if($lookup_array !== false)
	{
		foreach($lookup_array as $dinfo)
		{
			$domain = $dinfo['domain'];
			$domain_array[] = $domain;
			if($domain_names != "")
				$domain_names .= ",";
			$domain_names .= $domain;
			CheckBlackListsForDomainMX($pdo, $domain);
		}
		if($verbose)
			smartEcho($domain_names);
	}
	else
	{
		smartEcho($pdo->getLastError());
		exit;
	}
}

#########################################################################################################

function CheckBlackListsForDomainMX($pdo, $domain)
{
	global $verbose, $dnsbl_lookup_array, $refresh_days;
	$count = 0;
	$sid = $pdo->getSingleEntry($pdo->getDomainTableName(), "domain", $domain, "sid"); 
	if($sid !== false && $sid > 0)
	{
		$done_data = array();
		$sdinfo = $pdo->getTableData($pdo->getSubdomainTableName(), "hid,subdomain,record_type,record_value,ip", "where sid = $sid");
		foreach($sdinfo as &$sdi)
		{
			if(isset($sdi['record_type']))
			{
				$ipadd = "";
				if(isset($sdi['ip']))
					$ipadd = $sdi['ip'];
				else if(isset($sdi['record_value']) && $sdi['record_type'] == "MX")
				{
					$value = $sdi['record_value'];
					$vparts = explode(" ", $value);
					if(count($vparts) == 2)
					{
						$value = $vparts[1];
						$ipa = gethostbyname($value);
						if($ipa != $value)
						{
							$ipadd = $ipa;
							$sdi['ip'] = $ipadd;
						}
					}
				}
				if(($sdi['record_type'] == "MX" || $sdi['record_type'] == "A") && $ipadd != "")
				{
					if(!array_key_exists($ipadd, $done_data))
					{
						$listed = CheckIPAddressInDNSBL($ipadd, $dnsbl_lookup_array);
						$done_data[$ipadd] = $listed;
					}
					else
						$listed = $done_data[$ipadd];
					$count++;
					$dnsblinfo = implode(",", $listed);
					if($dnsblinfo == "")
						$dnsblinfo = "-";
					$sdi['notes_d'] = $dnsblinfo;
					$sdi['id' ] = $sdi['hid'];
					if($verbose)
					{
						if(!is_cli())
							echo "<pre>";
						print_r($sdi);
					}
					update_subdomain_table($sdi, $sdi['subdomain'], $domain);
				}
			}
		}
		if(count($done_data))
			$dataarray['ipbl_checked_at'] = date("Y-m-d H:i:s");
		else
			$dataarray['ipbl_checked_at'] = date("Y-m-d H:i:s", time() - (($refresh_days+1) * 86400));
		$pdo->setDomainDataFromArray($domain, $dataarray);
	}	
	return $count ? true : false;
}

#########################################################################################################

function CheckIPAddressInDNSBL($ip, $dnsbl_lookup_array)
{
	global $verbose;
    $listed = array();
    if ($ip) 
	{
        $reverse_ip = implode(".", array_reverse(explode(".", $ip)));
        foreach ($dnsbl_lookup_array as $host) 
		{
			$start = microtime(true);
            if (checkdnsrr($reverse_ip . "." . $host . ".", "A")) 
			{
				$listed[] = $host;
            }
			$time_elapsed_secs = microtime(true) - $start;
			if($verbose)
			{
				echo "$host $time_elapsed_secs, ";
			}
        }
		if($verbose)
		{
			echo "\n";
			echo implode("|", $listed);
			echo "\n";
		}
    }
	return $listed;
}

#########################################################################################################
?>
