@ character before fopen added to avoid annoing log lines
[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   function exists_in_rbl($remote) {
58     $rbls = array('http.dnsbl.sorbs.net', 'misc.dnsbl.sorbs.net');
59     //    $remote = $_SERVER['REMOTE_ADDR'];
60     // $remote = '213.134.170.206';
61     // $remote = '64.34.166.71';
62     
63     if (preg_match("/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/",
64                    $remote, $matches)) {
65       foreach ($rbls as $rbl) {
66         $rblhost = $matches[4] . "." . $matches[3] . "." .
67           $matches[2] . "." . $matches[1] . "." . $rbl;
68         
69         $resolved = gethostbyname($rblhost);
70         // echo "RBL ".$rblhost."<br>";
71         if ($resolved != $rblhost) {
72           return TRUE;
73         }
74       }
75     }
76     return FALSE;
77   }
78   
79   /**
80    * VOID setHeader( STRING $trigger )
81    *    Set new header trigger...
82    */
83   function setHeader($trigger){
84     $this->scan_headers[] = $trigger;
85   }
86
87
88   /**
89    * ARRAY $triggers = getHeaders( VOID )
90    *    Get all triggers in one array
91    */
92   function getHeaders(){
93     return $this->scan_headers;
94   }
95
96
97   /**
98    * VOID setConfig( STRING $key,  STRING $value)
99    *    Set config line...
100    */
101   function setConfig($key,$value){
102     $this->config[$key] = $value;
103   }
104
105
106   /**
107    * MIXED $config = getConfig( [STRING $key] )
108    *    Get all config in one array, or only one config value as a string.
109    */
110   function getConfig($key=''){
111     if($key)
112       return $this->config[$key];
113     else
114       return $this->config;
115   }
116
117
118   /**
119    * STRING $log = getLog( VOID )
120    *    Get last logged information. Only works AFTER calling detect()!
121    */
122   function getLog(){
123     return $this->lastLog;
124   }
125
126
127   /**
128    * BOOL $proxy = detect( VOID )
129    *    Start detection and return TRUE if a proxy server is detected...
130    */
131   function detect(){
132     GLOBAL $G_proxy_white_list;
133     $log = "";
134
135     foreach($G_proxy_white_list as $authproxy) {
136       if ($_SERVER['REMOTE_ADDR'] == $authproxy)
137         return (FALSE);
138     }
139
140     if ($this->exists_in_rbl($_SERVER['REMOTE_ADDR']) == TRUE)
141       return (TRUE);
142
143 //     //scan all headers
144 //     foreach($this->scan_headers as $i){
145 //       //proxy detected? lets log...
146 //       if($_SERVER[$i])
147 //      $log.= "trigger $i: ".$_SERVER[$i]."\n";
148 //     }
149
150     //let's do something...
151     if($log){
152       $log = $this->lastLog = date("Y-m-d H:i:s")."\nDetected proxy server: ".gethostbyaddr($_SERVER['REMOTE_ADDR'])." ({$_SERVER['REMOTE_ADDR']})\n".$log;
153
154       //mail message
155       if($this->getConfig('MAIL_ALERT_TO'))
156         mail($this->getConfig('MAIL_ALERT_TO'),"Proxy detected at {$_SERVER['REQUEST_URI']}",$log);
157
158       //write to file
159       $f = $this->getConfig('LOG_FILE');
160       if($f){
161         if(is_writable($f)){
162           $fp = fopen($f,'a');
163           fwrite($fp,"$log\n");
164           fclose($fp);
165         }else{
166           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...");
167         }
168       }
169
170       //done
171       return TRUE;
172     }
173
174     //nope, no proxy was logged...
175     return FALSE;
176   }
177 }
178
179 //init class
180 function is_proxy()
181 {
182   $proxy = new proxy_detector();
183   
184   //start detect
185   if($proxy->detect()) {
186     //returned TRUE, lets die...
187     echo "<br><br><div style=\"text-align:center;\"><h1>Accesso attaverso proxy non consentito.</h1><br><br>";
188     echo "Se state utilizzando un proxy privato e volete che sia autorizzato mandate il suo indirizzo IP (".$_SERVER['REMOTE_ADDR'].") e il suo proprietario all'indirizzo di posta elettronica <a href=\"mailto:brisk@alternativeoutput.it\">brisk@alternativeoutput.it</a><br><br></div>";
189     
190     //parse logged info
191     echo nl2br($proxy->getLog());
192     
193     //some credits...
194     // echo "<hr><strong>proxy detector v0.1</strong> - &copy;2006 <a href=\"http://www.daantje.nl\" target=\"_blank\">daantje.nl</a>";
195     
196     //and do nothing anymore! (but not in my example)
197     return (TRUE);
198   }
199   else
200     return (FALSE);
201 }
202
203 ?>