File: _functions_antispam.php

package info (click to toggle)
b2evolution 0.9.2-3
  • links: PTS
  • area: main
  • in suites: etch-m68k
  • size: 12,976 kB
  • ctags: 5,460
  • sloc: php: 58,989; sh: 298; makefile: 36
file content (304 lines) | stat: -rw-r--r-- 8,406 bytes parent folder | download | duplicates (2)
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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
<?php
/**
 * Antispam handling functions
 * 
 * b2evolution - {@link http://b2evolution.net/}
 * Released under GNU GPL License - {@link http://b2evolution.net/about/license.html}
 * @copyright (c)2003-2005 by Francois PLANQUE - {@link http://fplanque.net/}
 *
 * @package evocore
 */
if( !defined('DB_USER') ) die( 'Please, do not access this page directly.' );


/**
 * antispam_create(-)
 *
 * Insert a new abuse string into DB
 */
function antispam_create( $abuse_string, $aspm_source = 'local' )
{
	global $DB, $querycount, $tableantispam;
	
	// Cut the crap if the string is empty:
	$abuse_string = trim( $abuse_string );
	if( empty( $abuse_string ) ) return false;
	
	// Check if the string already is in the blacklist:
	if( antispam_check($abuse_string) ) return false;
	
	// Insert new string into DB:
	$sql = "INSERT INTO $tableantispam( aspm_string, aspm_source )
					VALUES( '".$DB->escape($abuse_string)."', '$aspm_source' )";
	$DB->query( $sql );

	return true;
}


/**
 * antispam_update_source(-)
 *
 * Note: We search by string because we sometimes don't know the ID 
 * (e-g when download already in list/cache)
 */
function antispam_update_source( $aspm_string, $aspm_source )
{
	global $DB, $tableantispam, $querycount;
	
	$sql = "UPDATE $tableantispam 
					SET aspm_source = '$aspm_source' 
					WHERE aspm_string = '".$DB->escape($aspm_string)."'";
	$DB->query( $sql );
}

/*
 * antispam_delete(-)
 *
 * Remove an entry from the ban list
 */
function antispam_delete( $string_ID )
{
	global $tableantispam, $DB;

	$sql = "DELETE FROM $tableantispam 
					WHERE aspm_ID = $string_ID";
	$DB->query( $sql );
}


/**
 * Check if a string contains abusive substrings
 *
 * Note: Letting the database do the LIKE %% match is a little faster than doing in it PHP,
 * not to mention the incredibly long overhead of preloading the list into PHP
 *
 * @return string balcklisted keyword found or false if no spam detected
 */
function antispam_check( $haystack )
{
 	global $DB;

	if( $block = $DB->get_var( "SELECT aspm_string
					  		 	FROM  T_antispam
					       WHERE ".$DB->quote($haystack)." LIKE CONCAT('%',aspm_string,'%')
					       LIMIT 0, 1", 0, 0, 'Check URL against antispam balcklist' ) )
	{
			debug_log( 'Spam block: '.$block );
			return $block;	// SPAM detected!
	}

	return false;	// no problem.

}


/*
 * list_antiSpam(-)
 *
 * Extract anti-spam
 */
function list_antiSpam()
{
	global $DB, $querycount, $tableantispam, $res_stats;

	$sql = "SELECT aspm_ID, aspm_string, aspm_source 
					FROM $tableantispam 
					ORDER BY aspm_string ASC";
	$res_stats = $DB->get_results( $sql, ARRAY_A );
}

/*
 * antiSpam_ID(-)
 */
function antiSpam_ID()
{
	global $row_stats;
	echo $row_stats['aspm_ID'];
}

/**
 * {@internal antiSpam_domain(-)}}
 *
 * @param mixed max length or false if we don't want to display
 */
function antiSpam_domain( $dispmax = 80 )
{
	global $row_stats;
	$domain = $row_stats['aspm_string'];
	if( ! $dispmax )
		return $domain;

	$domain = htmlspecialchars($domain);

	if( strlen( $domain ) > $dispmax )
		echo substr( $domain, 0, $dispmax ), '...';
	else
		echo $domain;
}


/*
 * antiSpam_domain(-)
 */
function antispam_source( $disp = true, $raw = false )
{
	global $row_stats, $aspm_sources;
	$asp_source = $row_stats['aspm_source'];
	if( ! $raw )
		$asp_source = T_(	$aspm_sources[$asp_source] );
	if( $disp )
		echo $asp_source;
	else
		return $asp_source;
}


// -------------------- XML-RPC callers ---------------------------

/*
 * b2evonet_report_abuse(-)
 *
 * pings b2evolution.net to report abuse from a particular domain
 */
function b2evonet_report_abuse( $abuse_string, $display = true )
{
	global $debug, $antispamsrv_host, $antispamsrv_port, $antispamsrv_uri;

	global $baseurl;
	if( $display )
	{	
		echo "<div class=\"panelinfo\">\n";
		echo '<h3>'.T_('Reporting abuse to').' '.$antispamsrv_host."...</h3>\n";
	}
	if( !preg_match( '#^http://localhost[/:]#', $baseurl) || ( $antispamsrv_host == 'localhost' ) )
	{	// Local install can only report to local test server
		// Construct XML-RPC client:
		$client = new xmlrpc_client( $antispamsrv_uri, $antispamsrv_host, $antispamsrv_port);
		$client->debug = $debug;
		
		// Construct XML-RPC message:
		$message = new xmlrpcmsg( 
									'b2evo.reportabuse',	 											// Function to be called
									array( 
										new xmlrpcval(0,'int'),										// Reserved
										new xmlrpcval('annonymous','string'),			// Reserved
										new xmlrpcval('nopassrequired','string'),	// Reserved
										new xmlrpcval($abuse_string,'string'),		// The abusive string to report
										new xmlrpcval($baseurl,'string'),					// The base URL of this b2evo
									)  
								);
		$result = $client->send($message);
		if( $ret = xmlrpc_displayresult( $result ) )
		{	// Remote operation successful:
			antispam_update_source( $abuse_string, 'reported' );
		}

		if( $display ) echo '<p>', T_('Done.'), "</p>\n</div>\n";
		return($ret);
	} 
	else 
	{
		if( $display ) echo "<p>", T_('Aborted (Running on localhost).'), "</p>\n</div>\n";
		return(false);
	}
}


/*
 * b2evonet_poll_abuse(-)
 *
 * request abuse list from central blacklist
 */
function b2evonet_poll_abuse( $display = true )
{
	global $Settings, $baseurl, $debug, $antispamsrv_host, $antispamsrv_port, $antispamsrv_uri;
	
	if( $display )
	{	
		echo "<div class=\"panelinfo\">\n";
		echo '<h3>', T_('Requesting abuse list from').' '.$antispamsrv_host.'...', "</h3>\n";
	}

	// Construct XML-RPC client:
	$client = new xmlrpc_client( $antispamsrv_uri, $antispamsrv_host, $antispamsrv_port);
	$client->debug = $debug;
	
	// Get datetime from last update, because we only want newer stuff...
	$m = $Settings->get( 'antispam_last_update' );
	// Encode it in the XML-RPC format
	echo '<p>', T_('Latest update timestamp'), ': ', $m, '</p>';
	$startat = mysql2date( 'Ymd\TH:i:s', $m );
	//$startat = iso8601_encode( mktime(substr($m,11,2),substr($m,14,2),substr($m,17,2),substr($m,5,2),substr($m,8,2),substr($m,0,4)) );
	
	// Construct XML-RPC message:
	$message = new xmlrpcmsg( 
								'b2evo.pollabuse',	 													// Function to be called
								array( 
									new xmlrpcval(0,'int'),											// Reserved
									new xmlrpcval('annonymous','string'),				// Reserved
									new xmlrpcval('nopassrequired','string'),		// Reserved
									new xmlrpcval($startat,'dateTime.iso8601'),	// Datetime to start at
									new xmlrpcval(0,'int')											// Reserved
								)  
							);
	$result = $client->send($message);
	
	if( $ret = xmlrpc_displayresult( $result ) )
	{	// Response is not an error, let's process it:
		$response = $result->value();
		if( $response->kindOf() == 'struct' )
		{	// Decode struct:
			$response = xmlrpc_decode_recurse($response);
			if( !isset( $response['strings'] ) || !isset( $response['lasttimestamp'] ) )
			{	
				echo T_('Incomplete reponse.')."\n";
				$ret = false;
			}
			else
			{	// Start registering strings: 
				$value = $response['strings'];
				if( count($value) == 0 )
				{
					echo '<p>', T_('No new blacklisted strings are available.'), '</p>';
				}
				else
				{	// We got an array of strings:
					echo '<p>', T_('Adding strings to local blacklist'), ':</p><ul>';
					foreach($value as $banned_string)
					{
						echo '<li>', T_('Adding:'), ' [', $banned_string, '] : ';
						if( antispam_create( $banned_string, 'central' ) )
						{	// Creation successed
							echo T_('OK.');
						}
						else
						{ // Was already handled
							echo T_('Not necessary! (Already handled)');
							antispam_update_source( $banned_string, 'central' );
						}
						echo '</li>';
					}
					echo '</ul>';
					// Store latest timestamp:
					$endedat = date('Y-m-d H:i:s', iso8601_decode($response['lasttimestamp']) );
					echo '<p>', T_('New latest update timestamp'), ': ', $endedat, '</p>';
					
					$Settings->set( 'antispam_last_update', $endedat );
					$Settings->updateDB();
				}				
			}
		}
		else
		{
			echo T_('Invalid reponse.')."\n";
			$ret = false;
		}
	}

	if( $display ) echo '<p>', T_('Done.'), "</p>\n</div>\n";
	return($ret);
}


?>