Vendredi 7 septembre 2007
<?php
/**
* Exit Node Detector
*
* Check if an IP address is an exit node of Tor network
* @author Matteo Carli <matteo@matteocarli.com>
* @copyright Copyright © 2007, Matteo Carli
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
* @version 1.0
*/
/**
* Really simple configuration
*
* Tips: cache path should be
* out of document root
*/
$cache_path = '../cache/'; //relative or absolute path from this file
$uri = 'https://nighteffect.us/tns/ip_list_exit.php/Tor_ip_list_EXIT.csv';
$cache_lifetime = 3600;
/**
* Get param from GET
*/
$ip_to_check = trim($_GET['ip']);
if (empty($ip_to_check))
$ip_to_check = $_SERVER['REMOTE_ADDR'];
elseif ($ip_to_check != long2ip(ip2long($ip_to_check)))
xml_response_error('Given IP address is not valid');
/**
* Require cache_lite
* (PEAR package)
*/
require_once('Cache/Lite.php');
$options = array(
'cacheDir' => $cache_path,
'lifeTime' => $cache_lifetime,
'automaticSerialization' => true
);
$cache = new Cache_Lite($options);
/**
* Get cache data
*/
if ($ips = $cache->get('exit_node')) {
/**
* Prepare xml document
* for ip given
*/
xml_response(in_array($ip_to_check,$ips),$ip_to_check);
/**
* If cache data is not available
* get ips from URL
*/
} else {
/**
* Check if CURL is installed
*/
if (!function_exists('curl_init')) {
xml_response_error('CURL is not installed');
}
/**
* Get the list
*/
$http = curl_init($uri);
curl_setopt($http, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; it; rv:1.8.1.1) Gecko/2006 TorDetector/1.0');
curl_setopt($http, CURLOPT_REFERER, 'http://nighteffect.us/tns/index.php');
curl_setopt($http, CURLOPT_HEADER, false);
curl_setopt($http, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($http, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($http);
/**
* If there is an error when
* retrive the ips get the
* cached element anyway
*/
if(curl_errno($http)!=0 or curl_getinfo($http,CURLINFO_HTTP_CODE)!=200) {
if ($ips = $cache->get('exit_node','default',true)) {
/**
* Prepare xml document
* for given ip
*/
xml_response(in_array($ip_to_check,$ips),$ip_to_check);
} else {
xml_response_error('Cache not found after HTTP error.');
}
}
curl_close($http);
/**
* Split and sanitize ips
* getted from CVS
*/
$ips = split("n",$response);
foreach ($ips as $k => $ip) {
$ip = trim($ip);
if (empty($ip))
unset($ips[$k]);
elseif ($ip != long2ip(ip2long($ip)))
unset($ips[$k]);
}
/**
* Store the cache
*/
$cache->save($ips);
/**
* Prepare xml document
* for given ip
*/
xml_response(in_array($ip_to_check,$ips),$ip_to_check);
}
/**
* Prepare xml document for error report
*/
function xml_response_error($error='No additional information')
{
/**
* Output xml header
*/
header('Content-type: text/xml; charset=UTF-8', true);
echo '<?xml version="1.0" encoding="UTF-8" ?>';
echo "n<tor>";
/**
* Print out error information
*/
echo "nt<error>true</error>";
echo "nt<error_information>".$error."</error_information>";
echo "n</tor>";
exit(1);
}
/**
* Prepare xml document for given ip information report
*/
function xml_response($code,$ip='')
{
header('Content-type: text/xml; charset=UTF-8', true);
echo '<?xml version="1.0" encoding="UTF-8" ?>';
echo "n<tor>";
/**
* Output information about ip
* address given
*/
echo "nt<tor_exit_node>";
echo $code ? 'true' : 'false';
echo "</tor_exit_node>";
echo "nt<tor_exit_node_ip>".$ip."</tor_exit_node_ip>";
echo "n</tor>";
exit(1);
}
?>