TightURL

TightURL Git Source Tree

Root/tighturl.lib.inc.php

1<?php
2define("TLVERSION", "0.1.4");
3define("TLREQUIRED_PHP_VERSION", "4.3.0");
4error_reporting (E_ALL);
5
6// You REALLY don't want to edit below here unless you know what you're doing.
7
8// *************************************************************************
9
10 if (version_compare(phpversion(), REQUIRED_PHP_VERSION)<0) {
11 die("$svcname Error: TightURL ".VERSION." needs PHP >= ".REQUIRED_PHP_VERSION." (you are using ".phpversion().")");
12 }
13
14
15$validipv4pattern = "/^(http|https|ftp|sftp):\/\/(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.";
16$validipv4pattern .= "(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])";
17$validipv4pattern .= "\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\/*/";
18
19// ****** !All overridable configuration variables must go above this line! ******
20
21function TightURL_version_check() {
22 global $VUCycle;
23
24 // check http://tighturl.com/version.php and/or http://tighturl.sf.net/version.php
25 // parse out if there's a security release
26 // notify admin of this tighturl installation once if there's a new version,
27 // once a week, if there's a security fix.
28 // Possibly display "newer version available" on templates.
29 // Possibly disable vulnerable versions after a certain amount of time.
30 // ie, only show "Site down for emergency maintenance. If you are the administrator, click here."
31 // validate against mysql database password, show vulnerability screen.
32
33 if ($VUCycle < 24) $VUCycle = 24; // someone's trying to get banned.
34}
35
36/**
37 * Checks accepted URLs against URI blacklists and marks listed URLs as abused.
38 */
39function TightURL_KillBot($query='') {
40
41 global $dbtable;
42
43 if ($query == "") $query="SELECT * FROM $dbtable;";
44
45 // Query records with status normal, and added within last 2 weeks or records with status normal and more than 7 hits and hit within the last 2 weeks
46 // "SELECT * FROM $dbtable where status=0 && (DATE_SUB(CURDATE(), INTERVAL 14 DAY) <= adddate || (hits > 7 && DATE_SUB(CURDATE(), INTERVAL 14 DAY) <= lasthit)) ORDER BY id;"
47 $set = mysql_query($query);
48 $rows = @mysql_num_rows($set) or $rows = 0;
49
50 for ($i = 0; $i <$rows; $i++) {
51
52 $row = mysql_fetch_array($set);
53 $id = $row["id"];
54 $url = $row["url"];
55 $status = $row["status"];
56 $hits = $row["hits"];
57
58 $hit = URI_on_URIBL($url);
59 if ($hit) {
60 // Change this to disable instead of delete, delete at some future point.
61 $req ="update $dbtable set status=3 where id='$id';";
62 $res = mysql_query($req);
63 }
64// elseif ($hits > 4000) {
65// // Change this to disable instead of delete, delete at some future point.
66// $req ="update $dbtable set status=5 where id='$id';";
67// $res = mysql_query($req);
68// }
69 else {
70 $req = "update $dbtable set lastcheck=NOW(), checkcount=checkcount+1 where id='$id';";
71 $res = mysql_query($req);
72 }
73 }
74}
75
76function TightURL_NewReport($query='') {
77
78 global $dbtable;
79
80 if ($query == "") $query="SELECT * FROM $dbtable;";
81
82 $set = mysql_query($query);
83 $rows = @mysql_num_rows($set) or $rows = 0;
84
85 if ($rows > 0) {
86 $MP = "/usr/sbin/sendmail -t ron@vnetworx.net";
87 $fd = popen($MP, "w");
88 fputs($fd, "To: ron@vnetworx.net\n");
89 fputs($fd, "From: killbot@tighturl.com <killbot@tighturl.com>\n");
90 fputs($fd, "Subject: TightURL additions report\n");
91 fputs($fd, "\n");
92
93 for ($i = 0; $i <$rows; $i++) {
94 $row = mysql_fetch_array($set);
95 $id = $row["id"];
96 $url = $row["url"];
97 fputs($fd, "Block: http://tighturl.com/?p=" . base_convert($id, 10, 36) . " URL: $url\n\n");
98 }
99 pclose($fd);
100 }
101}
102
103/**
104 * Checks to see if a given URI is on a URI blacklist.
105 * Currently this means SURBL (http://www.surbl.org) and URIBL (http://www.uribl.com)
106 *
107 * Returns TRUE if the domain is listed on any configured URIBLs.
108 *
109 * A companion URI extractor must be written for the below issues
110 * Must be changed to do full resolution of redirections on URI, simulating a browser
111 * Must be changed to do IPv6 lookups
112 * Must be changed to check multiple URIs
113 * Must be changed to optionally check HTML entity encoded versions of URIs
114 * Must be changed to handle URIBL's inclusion of some third-level domains.
115 *
116 */
117function URI_on_URIBL($uri) {
118
119// This code does not yet properly implement a correct and efficient querying
120// of URI BL data.
121
122 global $uribl, $uribluri, $validurlpattern, $validipv4pattern, $tltlds, $validschemes;
123
124 $uribls = "";
125
126 if ($uri) {
127 // Test for IPv4 address, reverse the quads if found
128 if (preg_match($validipv4pattern,$uri,$matches)) {
129 $domain=$matches[5] . "." . $matches[4] . "." . $matches[3] . "." . $matches[2];
130 }
131 else {
132 // strip out second-level domain name, *unless* on exception list,
133 // in which case, strip out third level also and test that instead.
134 preg_match("/^".$validschemes.$validurlpattern."$/", $uri, $matches);
135 //preg_match($validurlpattern, $uri, $matches);
136 $domain = $matches[4];
137 if (preg_match("/".$tltlds."$/", $domain, $matches)) {$levels = 2;} else {$levels = 1;}
138 //if (preg_match($tltlds, $domain, $matches)) {$levels = 2;} else {$levels = 1;}
139
140 // klugey stripping routine to reduce domain to base domain name
141 // expect regex wojuld be better
142// (.*\..*){2} matches vnetworx.co.uk but not vnetworx.com
143// .*(\.co\.uk) matches[1] .co.uk
144
145 $ss = countSubstrs($domain, ".");
146 while ($ss > $levels) {
147 $chop = strpos($domain, ".");
148 $domain = substr($domain, $chop + 1);
149 $ss = countSubstrs($domain, ".");
150 }
151 }
152
153 // Query URI blacklists to see if domain/IP appears as target in known spam
154 // or something involved in a malware/phishing attack.
155 for ($i=0; $i<count($uribl); $i++) {
156 $fqdn = $domain . "." . $uribl[$i];
157 $recexists = gethostbyname($fqdn); // ghbn weirdly returns the name on failure
158 if ($recexists != $fqdn) {
159 if ($i > 0) $uribls .= ", ";
160 $uribls .= $uribl[$i];
161 }
162 }
163 if ($uribls) return $uribls; else return FALSE; // change to return an array of indexes into the URIBL array
164 }
165}
166
167/**
168 * Checks to see if a given URL is a Reserved URL.
169 *
170 * Returns TRUE if the ID is listed as a Reserved URL.
171 */
172function on_Reserve($decimal) {
173 global $ReservedURL;
174
175 $res=FALSE;
176
177 if ($decimal) {
178 $sexatrigesimal = base_convert($decimal, 10, 36);
179 for ($i=0; $i<count($ReservedURL); $i++) {
180 if ($sexatrigesimal == strtolower($ReservedURL[$i])) return TRUE;
181 }
182 return FALSE;
183 }
184}
185
186function http_headers ($uri) {
187 array ($headers);
188 // Split URI into host and resource parts
189 $parsed = parse_url($uri);
190
191 if ($parsed[port] == 0) $parsed[port] = 80;
192
193 $connection = fsockopen ($parsed[host], $parsed[port]);
194 if ($connection) {
195 stream_set_timeout($connection, 2);
196 fwrite($connection, "HEAD $parsed[path] HTTP/1.1\r\nHOST: $parsed[host]\r\n\r\n");
197 while (!feof($connection)) {
198 $line_read=fgets($connection);
199 if ($line_read == "") break;
200 $headers[] = $line_read;
201 }
202 fclose ($connection);
203 }
204 return $headers;
205}
206
207// ***************** Non-TightURL-specific functions *********************
208
209/**
210 * sanitize a string for MySQL input
211 */
212if (! function_exists('sanitize_sql_string')) {
213 function sanitize_sql_string($string) {
214 if (get_magic_quotes_gpc()) $string = stripslashes($string);
215 return mysql_escape_string($string);
216 }
217}
218
219/**
220 * Counts the number of times a substring is contained in a given string.
221 */
222if (! function_exists('countSubstrs')) {
223 function countSubstrs($haystack, $needle) {
224 return (($p = strpos($haystack, $needle)) === false) ? 0 : (1 + countSubstrs(substr($haystack, $p+1), $needle));
225 }
226}
227
228// ***************** PHP compatibility functions *********************
229
230/**
231 * Add back get_magic_quotes_gpc() if this is PHP6 or later
232 */
233if (! function_exists('get_magic_quotes_gpc')) {
234 function get_magic_quotes_gpc()
235 {
236 return 0;
237 }
238}
239
240/**
241 * Add in version_compare for PHP < 4.0.7
242 */
243if (! function_exists('version_compare')) {
244 function version_compare($version1, $version2)
245 {
246 $v1 = explode('.', $version1);
247 $v2 = explode('.', $version2);
248
249 if ($v1[0] > $v2[0]) $ret = 1;
250 elseif ($v1[0] < $v2[0]) $ret = -1;
251 else {
252 // Major version numbers are equal
253 if ($v1[1] > $v2[1]) $ret = 1;
254 elseif ($v1[1] < $v2[1]) $ret = -1;
255 else {
256 // Minor version numbers are equal
257 if ($v1[2] > $v2[2]) $ret = 1;
258 elseif ($v1[2] < $v2[2]) $ret = -1;
259 else $ret = 0;
260 }
261 }
262 return $ret;
263 }
264}
265
266/**
267 * Add in file_get_contents for PHP < 4.3.0
268 */
269if (! function_exists('file_get_contents')) {
270 function file_get_contents($filename, $incpath = false, $resource_context = null)
271 {
272 if (false === $fh = fopen($filename, 'rb', $incpath)) {
273 trigger_error('file_get_contents() failed to open stream: No such file or directory', E_USER_WARNING);
274 return false;
275 }
276 clearstatcache();
277 if ($fsize = @filesize($filename)) $data = fread($fh, $fsize);
278 else {
279 $data = '';
280 while (!feof($fh)) $data .= fread($fh, 8192);
281 }
282 fclose($fh);
283 return $data;
284 }
285}
286
287?>

Archive Download this file

Branches