ProxyDetector
[ class tree: ProxyDetector ] [ index: ProxyDetector ] [ all elements ]

Source for file proxydetector.class.php

Documentation is available at proxydetector.class.php

  1. <?php
  2. /**
  3.  * ProxyDetector v1.0
  4.  * Copyright (c) 2008, Atikae (Hugo Busiere) <atikae@gmail.com>
  5.  * All rights reserved.
  6.  * See COPYING file for more informations
  7.  * 
  8.  * Main class of ProxyDetector.
  9.  * 
  10.  * @author Atikae (Hugo Busiere) <atikae@gmail.com>
  11.  * @version 1.0
  12.  * @licence COPYING BSD licence
  13.  * @package ProxyDetector
  14.  * 
  15.  * @todo Find tips for detect CGI-Proxy which are currently undetectable with following methods
  16.  * 
  17.  */
  18.  
  19. /**
  20.  * Include config class & config options
  21.  */
  22. require_once 'config.php';
  23.  
  24. /**
  25.  * This is the main class of ProxyDetector Project.
  26.  * 
  27.  * All check is here.
  28.  * @package ProxyDetector
  29.  * @subpackage mainclass
  30.  */
  31. class ProxyDetector {
  32.     
  33.     /**
  34.      * Using Tor Check ? (read in config)
  35.      * 
  36.      * @link https://www.torproject.org/tordnsel/
  37.      * @access protected
  38.      * @var boolean 
  39.      *  See {@link Config::$useTor}
  40.      */
  41.     var $useTor = false;
  42.     
  43.     /**
  44.      * URI of TORdnsel server
  45.      * @access protected
  46.      * @var string 
  47.      */
  48.     var $torNodeList;
  49.     
  50.     /**
  51.      * HTTP headers characteristic of a Proxy
  52.      * 
  53.      * Some "imposed" headers and user can add alternative header in Config::headers
  54.      * @access protected
  55.      * @var array 
  56.      *  See {@link Config::$headers}
  57.      */
  58.     var $forbiddenHeaders = array();
  59.     
  60.     /**
  61.      * Array resume errors found
  62.      * @see Config()
  63.      * @access protected
  64.      * @var array 
  65.      */
  66.     var $detected = array('Headers' => array()'Tor' => false'VPN'/*currently not implemented*/);
  67.     
  68.     
  69.     /**
  70.      * Constructor check for session_name {@link Config::$session_name},
  71.      * 
  72.      * run {@link readConf()}{@link checkRequirement()} and {@link initHeaders()}
  73.      * 
  74.      */
  75.     function ProxyDetector({
  76.         if (session_id(== '')
  77.             session_start(Config::getConf('session_name'''));
  78.         $this->readConf();
  79.         $this->checkRequirement();
  80.         $this->initHeaders();
  81.     }
  82.     
  83.     /**
  84.      * Perfom some check, for ProxyDetector need
  85.      */
  86.     function checkRequirement({
  87.         if ($this->useTor{
  88.             if (strtoupper(substr(PHP_OS03)) !== 'WIN'{// nslookup always on windows
  89.                 $return exec('which dig');
  90.                 if (empty($return)) {
  91.                     echo 'dig command must be available on Linux/Unix system.<br />Download and install binutils';
  92.                     exit(-1);
  93.                 }
  94.             }
  95.         }
  96.     }
  97.     
  98.     /**
  99.      * Init {@link $useTor} and {@link $torNodeList}
  100.      */
  101.     function readConf({
  102.         $this->useTor = (bool)Config::getConf('useTor'false);
  103.         $this->torNodeList = (string)Config::getConf('torNodeAddr''ip-port.exitlist.torproject.org');
  104.     }
  105.     
  106.     /**
  107.      * Init {@link $forbiddenHeaders} using imposed headers and config header {@link Config::$headers}
  108.      */
  109.     function initHeaders({
  110.         $tmp array ('Via''X_forwarded''Client_ip''Forwarded');
  111.         $this->forbiddenHeaders = array_merge($tmp(array)Config::getConf('headers'array()));
  112.     }
  113.     
  114.     
  115.     /**
  116.      * Check if remote host is a Tor node
  117.      * 
  118.      * Basing on {@link https://www.torproject.org/tordnsel/}
  119.      * @param string $host host needed to check
  120.      * @return boolean True if host is tor node
  121.      */
  122.     function isTorNode($host{
  123.         if (strtoupper(substr(PHP_OS03)) === 'WIN')
  124.            exec('nslookup A '.escapeshellarg($host)$res);
  125.         else
  126.            exec('dig A '.escapeshellarg($host)$res);
  127.  
  128.         $res implode("\r\n"$res);
  129.  
  130.         if (strpos($res'127.0.0.2'!== false)
  131.             return true;
  132.         else
  133.             return false;
  134.     }
  135.     
  136.     /**
  137.      * Reverse Ip Addr
  138.      * @param string $ip IP to reverse
  139.      * @return string Reverse IP
  140.      */
  141.     function reverseAddr($ip{
  142.         $ip explode('.'$ip);
  143.         $ip array_reverse($ip);
  144.         return implode('.'$ip);
  145.     }
  146.     
  147.     /**
  148.      * Check HTTP headers, basing on {@link $forbiddenHeaders}
  149.      */
  150.     function performHeadersCheck({
  151.         foreach($_SERVER as $header => $value{
  152.             foreach($this->forbiddenHeaders as $forbid{
  153.                 if ($header == 'HTTP_'.strtoupper($forbid))
  154.                     $this->detected['Headers'][$forbid$value;
  155.             }
  156.         }
  157.     }
  158.     
  159.     /**
  160.      * Init and perform Tor Node Checking if user set {@link Config::$useTor}
  161.      */
  162.     function performTorCheck({
  163.         if (!$this->useTor)
  164.             return;
  165.         $remoteAddr ProxyDetector::reverseAddr($_SERVER['REMOTE_ADDR']);
  166.         $localAddr ProxyDetector::reverseAddr($_SERVER['SERVER_ADDR']);
  167.         $host $remoteAddr.'.'.$_SERVER['SERVER_PORT'].'.'.$localAddr.'.'.$this->torNodeList;
  168.         if (ProxyDetector::isTorNode($host'A'))
  169.             $this->detected['Tor'true;
  170.     }
  171.     
  172.     /**
  173.      * Prevent multiple-checking (base on sessions), perform all tests
  174.      * @return boolean True if it's good, false if proxy is detected
  175.      */
  176.     function performCheck({
  177.         if (isset($_SESSION['ProxyDetector']['remoteAddr']&& $_SESSION['ProxyDetector']['remoteAddr'== $_SERVER['REMOTE_ADDR']{
  178.             if ($_SESSION['ProxyDetector']['isProxy']{
  179.                 $this->detected = unserialize($_SESSION['ProxyDetector']['errors']);
  180.                 return false;
  181.             else
  182.                 return true;
  183.         }
  184.         
  185.         $this->performHeadersCheck();
  186.         $this->performTorCheck();
  187.         
  188.         $_SESSION['ProxyDetector']['remoteAddr'$_SERVER['REMOTE_ADDR'];
  189.         if (!empty($this->detected['Headers']|| $this->detected['Tor'== true{
  190.             $_SESSION['ProxyDetector']['errors'serialize($this->detected);
  191.             $_SESSION['ProxyDetector']['isProxy'true;
  192.             return false;
  193.         else
  194.             $_SESSION['ProxyDetector']['isProxy'false;
  195.         return true;
  196.     }
  197.     
  198.     /**
  199.      * Display file when Proxy is detecting, based on user file {@link Config::$errorFile}
  200.      */
  201.     function showFile({
  202.         @header('Content-Type: text/html; charset=utf-8');
  203.         
  204.         $trad Config::getConf('strings'array('en' => array('none' => 'None''yes' => 'Yes''no' => 'No')));
  205.         $lang Config::getConf('language''en');
  206.         if (!array_key_exists($lang$trad))
  207.             $lang 'en';
  208.             
  209.         $header '';
  210.  
  211.         if (empty($this->detected['Headers']))
  212.             $headers $trad[$lang]['none'].'<br />';
  213.         else {
  214.             foreach($this->detected['Headers'as $key => $value)
  215.                 $headers .= htmlentities($keyENT_QUOTES'UTF-8').' => '.htmlentities($valueENT_QUOTES'UTF-8').'<br />';
  216.         }
  217.  
  218.         if ($this->useTor)
  219.             $tor ($this->detected['Tor'$trad[$lang]['yes'$trad[$lang]['no']).'<br />';
  220.             
  221.         $fileName Config::getConf('errorFile''proxy.html').'-'.$lang;
  222.         if (file_exists($fileName)) {
  223.             $tmp @file($fileName);
  224.             $tmp str_replace('{HEADERS_HERE}'$headers$tmp);
  225.             $tmp str_replace('{TOR_HERE}'$tor$tmp);
  226.             echo implode(''$tmp);
  227.         else {
  228.             $tmp  '<html><body><p><h4>Headers detected :</h4>'.$headers.'</p>';
  229.             if ($this->useTor)
  230.                 $tmp .= '<p><h4>Using TOR ?</h4>'.$tor.'</p>';
  231.             $tmp .= '</body></html>';
  232.             
  233.             echo $tmp;
  234.         }
  235.     }
  236.     
  237.     /**
  238.      * Main function, run tests and display {@link Config::$errorFile} if it's needed
  239.      */
  240.     function process({
  241.         if (!$this->performCheck()) {
  242.             $this->showFile();
  243.             exit(0);
  244.         }
  245.     }
  246. }
  247.  
  248.  
  249.  
  250.     
  251. /**
  252.  * Function simplify proxy check
  253.  */
  254. function isProxy({
  255.     $proxy new ProxyDetector();
  256.     $proxy->process();
  257.     unset($proxy);
  258. }
  259.  
  260. ?>

Documentation generated on Tue, 26 Aug 2008 18:42:08 +0200 by phpDocumentor 1.4.1