ban for proxy use added
[brisk.git] / web / Obj / proxyscan.phh
1 <?php
2 /**
3  *      Proxy Detector v0.1
4  *              copyrights by: Daantje Eeltink (me@daantje.nl)
5  *                                              http://www.daantje.nl
6  *
7  *              first build: Mon Sep 18 21:43:48 CEST 2006
8  *              last build: Tue Sep 19 10:37:12 CEST 2006
9  *
10  *      Description:
11  *              This class can detect if a visitor uses a proxy server by scanning the
12  *              headers returned by the user client. When the user uses a proxy server,
13  *              most of the proxy servers alter the header. The header is returned to
14  *              PHP in the array $_SERVER.
15  *
16  *      License:
17  *              GPL v2 licence. (http://www.gnu.org/copyleft/gpl.txt)
18  *
19  *      Support:
20  *              If you like this class and find it usefull, please donate one or two
21  *              coins to my PayPal account me@daantje.nl
22  *
23  *      Todo:
24  *              Add open proxy black list scan.
25  */
26
27 class proxy_detector {
28
29   /**
30    * CONSTRUCTOR
31    *    Set defaults...
32    */
33   function proxy_detector(){
34     $this->config = array();
35     $this->lastLog = "";
36
37     //set default headers
38     $this->scan_headers = array(
39                                 'HTTP_VIA',
40                                 'HTTP_X_FORWARDED_FOR',
41                                 'HTTP_FORWARDED_FOR',
42                                 'HTTP_X_FORWARDED',
43                                 'HTTP_FORWARDED',
44                                 'HTTP_CLIENT_IP',
45                                 'HTTP_FORWARDED_FOR_IP',
46                                 'VIA',
47                                 'X_FORWARDED_FOR',
48                                 'FORWARDED_FOR',
49                                 'X_FORWARDED',
50                                 'FORWARDED',
51                                 'CLIENT_IP',
52                                 'FORWARDED_FOR_IP',
53                                 'HTTP_PROXY_CONNECTION'
54                                 );
55   }
56
57   /*
58     function exists_in_rbl($remote)
59     verify if an host is into a proxy black list or not
60    */
61   function exists_in_rbl($remote) {
62     $rbls = array('http.dnsbl.sorbs.net', 'misc.dnsbl.sorbs.net');
63     //    $remote = $_SERVER['REMOTE_ADDR'];
64     // $remote = '213.134.170.206';
65     // $remote = '64.34.166.71';
66     
67     if (preg_match("/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/",
68                    $remote, $matches)) {
69       foreach ($rbls as $rbl) {
70         $rblhost = $matches[4] . "." . $matches[3] . "." .
71           $matches[2] . "." . $matches[1] . "." . $rbl;
72         
73         $resolved = gethostbyname($rblhost);
74         // echo "RBL ".$rblhost."<br>";
75         if ($resolved != $rblhost) {
76           return TRUE;
77         }
78       }
79     }
80     return FALSE;
81   }
82   
83   /**
84    * VOID setHeader( STRING $trigger )
85    *    Set new header trigger...
86    */
87   function setHeader($trigger){
88     $this->scan_headers[] = $trigger;
89   }
90
91
92   /**
93    * ARRAY $triggers = getHeaders( VOID )
94    *    Get all triggers in one array
95    */
96   function getHeaders(){
97     return $this->scan_headers;
98   }
99
100
101   /**
102    * VOID setConfig( STRING $key,  STRING $value)
103    *    Set config line...
104    */
105   function setConfig($key,$value){
106     $this->config[$key] = $value;
107   }
108
109
110   /**
111    * MIXED $config = getConfig( [STRING $key] )
112    *    Get all config in one array, or only one config value as a string.
113    */
114   function getConfig($key=''){
115     if($key)
116       return $this->config[$key];
117     else
118       return $this->config;
119   }
120
121
122   /**
123    * STRING $log = getLog( VOID )
124    *    Get last logged information. Only works AFTER calling detect()!
125    */
126   function getLog(){
127     return $this->lastLog;
128   }
129
130
131   /**
132    * BOOL $proxy = detect( $addr )
133    *    Start detection and return TRUE if a proxy server is detected...
134    */
135   function detect($addr){
136     GLOBAL $G_proxy_white_list;
137     $log = "";
138
139     foreach($G_proxy_white_list as $authproxy) {
140       if ($addr == $authproxy)
141         return (FALSE);
142     }
143
144     if ($this->exists_in_rbl($addr) == TRUE)
145       return (TRUE);
146
147 //     //scan all headers
148 //     foreach($this->scan_headers as $i){
149 //       //proxy detected? lets log...
150 //       if($_SERVER[$i])
151 //      $log.= "trigger $i: ".$_SERVER[$i]."\n";
152 //     }
153
154     //let's do something...
155     if($log){
156       $log = $this->lastLog = date("Y-m-d H:i:s")."\nDetected proxy server: ".gethostbyaddr($addr)." ({$addr})\n".$log;
157
158       //mail message
159       if($this->getConfig('MAIL_ALERT_TO'))
160         mail($this->getConfig('MAIL_ALERT_TO'),"Proxy detected at {$addr}",$log);
161
162       //write to file
163       $f = $this->getConfig('LOG_FILE');
164       if($f){
165         if(is_writable($f)){
166           $fp = fopen($f,'a');
167           fwrite($fp,"$log\n");
168           fclose($fp);
169         }else{
170           die("<strong>Fatal Error:</strong> Couldn't write to file: '<strong>$f</strong>'<br>Please check if the path exists and is writable for the webserver or php...");
171         }
172       }
173
174       //done
175       return TRUE;
176     }
177
178     //nope, no proxy was logged...
179     return FALSE;
180   }
181 }
182
183 //init class
184 function is_proxy($addr)
185 {
186     /* FIXME: test to verify reasons of poor multitasking performances */
187     return (FALSE);
188     /* FIXME: end */
189
190   $proxy = new proxy_detector();
191   
192   //start detect
193   if($proxy->detect($addr)) {
194     //returned TRUE, lets die...
195     echo "<br><br><div style=\"text-align:center;\"><h1>Accesso attaverso proxy non consentito.</h1><br><br>";
196     echo "Se state utilizzando un proxy privato e volete che sia autorizzato mandate il suo indirizzo IP (".$addr.") e il suo proprietario all'indirizzo di posta elettronica <a href=\"mailto:brisk@alternativeoutput.it\">brisk@alternativeoutput.it</a><br><br></div>";
197     
198     //parse logged info
199     echo nl2br($proxy->getLog());
200     
201     //some credits...
202     // echo "<hr><strong>proxy detector v0.1</strong> - &copy;2006 <a href=\"http://www.daantje.nl\" target=\"_blank\">daantje.nl</a>";
203     
204     //and do nothing anymore! (but not in my example)
205     return (TRUE);
206   }
207   else
208     return (FALSE);
209 }
210
211 ?>