-
Notifications
You must be signed in to change notification settings - Fork 19
/
IP.Examine.class.php
189 lines (161 loc) · 5.97 KB
/
IP.Examine.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?php
/**
* File: IP.Examine.class.php
* This is the IP BlackList Examine class for the Geeklog Spam-X plugin
* Copyright (C) 2004-2010 by the following authors:
* Author Tom Willett tomw AT pigstye DOT net
* Licensed under GNU General Public License
*
* @package Spam-X
* @subpackage Modules
*/
if (stripos($_SERVER['PHP_SELF'], basename(__FILE__)) !== false) {
die('This file can not be used on its own!');
}
// Include Abstract Examine Class
require_once $_CONF['path'] . 'plugins/spamx/' . 'BaseCommand.class.php';
/**
* Examines Comment according to Personal IP Blacklist
*
* @author Tom Willett, tomw AT pigstye DOT net
* @package Spam-X
*/
class IP extends BaseCommand
{
/**
* The execute method examines the IP address a comment is coming from,
* comparing it against a blacklist of banned IP addresses.
*
* @param string $comment Comment text to examine
* @return int 0: no spam, else: spam detected
*/
public function execute($comment)
{
return $this->_process($_SERVER['REMOTE_ADDR']);
}
/**
* The re-execute method is used to mass-delete spam, essentially.
* It does the same as execute, but is called with recorded comments
* in order to match them against new rules that were not in effect
* at the time of posting. To do that, it uses the IP address logged
* when the comment was saved.
*
* @param string $comment Comment text to examine
* @param int $date Date/time the comment was posted
* @param string $ip IPAddress comment posted from
* @param string $type Type of comment ('article', etc)
* @return int 0: no spam, else: spam detected
*/
public function reexecute($comment, $date, $ip, $type)
{
return $this->_process($ip);
}
/**
* Private internal method to match an IP address against a CIDR
*
* @param string $iptocheck IP address to check
* @param string $CIDR IP address range to check against
* @return boolean true if IP falls into the CIDR, else false
* @todo CIDR support for IPv6 addresses
* Original author: Ian B, taken from
* @link http://www.php.net/manual/en/function.ip2long.php#71939
*/
private function _matchCIDR($iptocheck, $CIDR)
{
// not for IPv6 addresses
if (strpos($iptocheck, ':') !== false) {
return false;
}
// get the base and the bits from the ban in the database
list($base, $bits) = explode('/', $CIDR);
// now split it up into its classes
$classes = explode('.', $base);
$elements = count($classes);
if ($elements < 4) {
for ($i = $elements; $i < 4; $i++) {
$classes[$i] = 0;
}
}
list($a, $b, $c, $d) = $classes;
// now do some bit shifting/switching to convert to ints
$i = ($a << 24) + ($b << 16) + ($c << 8) + $d;
$mask = $bits == 0 ? 0 : (~0 << (32 - $bits));
// here's our lowest int
$low = $i & $mask;
// here's our highest int
$high = $i | (~$mask & 0xFFFFFFFF);
// now split the ip we're checking against up into classes
$ex = explode('.', $iptocheck);
if (count($ex) == 4) {
// now convert the ip we're checking against to an int
$check = ($ex[0] << 24) + ($ex[1] << 16) + ($ex[2] << 8) + $ex[3];
// if the ip is within the range, including
// highest/lowest values, then it's witin the CIDR range
if (($check >= $low) && ($check <= $high)) {
return true;
}
}
return false;
}
/**
* Private internal method to match an IP address against an address range
* Original authors: dh06 and Stephane, taken from
*
* @link http://www.php.net/manual/en/function.ip2long.php#70707
* @param string $ip IP address to check
* @param string $range IP address range to check against
* @return boolean true if IP falls into the IP range, else false
*/
private function _matchRange($ip, $range)
{
// not for IPv6 addresses
if (strpos($ip, ':') !== false) {
return false;
}
$d = strpos($range, '-');
if ($d !== false) {
$from = ip2long(trim(substr($range, 0, $d)));
$to = ip2long(trim(substr($range, $d + 1)));
$ip = ip2long($ip);
return (($ip >= $from) && ($ip <= $to));
}
return false;
}
/**
* Private internal method, this actually processes a given ip
* address against a blacklist of IP regular expressions.
*
* @param string $ip IP address of comment poster
* @return int 0: no spam, else: spam detected
*/
private function _process($ip)
{
global $_TABLES, $LANG_SX00;
$uid = $this->getUid();
/**
* Include Blacklist Data
*/
$result = DB_query("SELECT value FROM {$_TABLES['spamx']} WHERE name='IP'", 1);
$numRows = DB_numRows($result);
$ans = PLG_SPAM_NOT_FOUND;
for ($i = 0; $i < $numRows; $i++) {
list($val) = DB_fetchArray($result);
if (strpos($val, '/') !== false) {
$matches = $this->_matchCIDR($ip, $val);
} elseif (strpos($val, '-') !== false) {
$matches = $this->_matchRange($ip, $val);
} else {
$matches = preg_match("#^{$val}$#i", $ip);
}
if ($matches) {
$ans = PLG_SPAM_FOUND; // quit on first positive match
$this->updateStat('IP', $val);
SPAMX_log($LANG_SX00['foundspam'] . $val .
$LANG_SX00['foundspam2'] . $uid .
$LANG_SX00['foundspam3'] . $ip);
break;
}
}
return $ans;
}
}