Jump to content

Need mysql hooks to port 'bad-behavior' spam blocking services


neildaemond
 Share

Recommended Posts

I stumbled across bad-behavior spam blocker today and I'm trying to port it to Processwire. It looks like a decent service which is natively used in some other cms's and php apps.

out of the box, this service is supposed to work by downloading and unzipping the files to somewhere accessible, then adding

require_once("/path/to/Bad-Behavior/bad-behavior-generic.php");

To your pages. I added it at the top of PW's index.php. So, its supposed to be working (although I can't yet tell :P ).

However, its supposed to work even better if you can give it a database to enable logging. To do this, one has to add the mysql hooks into the bad-behavior-generic.php file. I think these are the lines that need to be modified:

// Bad Behavior callback functions.

// Return current time in the format preferred by your database.
function bb2_db_date() {
	return gmdate('Y-m-d H:i:s');   // Example is MySQL format
}

// Return affected rows from most recent query.
function bb2_db_affected_rows() {
	return false;
}

// Escape a string for database usage
function bb2_db_escape($string) {
	// return mysql_real_escape_string($string);
	return $string; // No-op when database not in use.
}

// Return the number of rows in a particular query.
function bb2_db_num_rows($result) {
	if ($result !== FALSE)
			return count($result);
	return 0;
}

// Run a query and return the results, if any.
// Should return FALSE if an error occurred.
// Bad Behavior will use the return value here in other callbacks.
function bb2_db_query($query) {
	return FALSE;
}

// Return all rows in a particular query.
// Should contain an array of all rows generated by calling mysql_fetch_assoc()
// or equivalent and appending the result of each call to an array.
function bb2_db_rows($result) {
	return $result;
}

// Create the SQL query for inserting a record in the database.
// See example for MySQL elsewhere.
function bb2_insert($settings, $package, $key)
{
	return "--";
}

// Return emergency contact email address.
function bb2_email() {
	return "example@example.com";   // You need to change this.
}

// retrieve whitelist
function bb2_read_whitelist() {
	return @parse_ini_file(dirname(BB2_CORE) . "/whitelist.ini");
}

// retrieve settings from database
// Settings are hard-coded for non-database use
function bb2_read_settings() {
	global $bb2_settings_defaults;
	$settings = @parse_ini_file(dirname(__FILE__) . "/settings.ini");
	if (!$settings) $settings = array();
	return @array_merge($bb2_settings_defaults, $settings);
}

// write settings to database
function bb2_write_settings($settings) {
	return false;
}

// installation
function bb2_install() {
	return false;
}

but I couldnt tell how to call the PW mysql hooks. For reference, the sample version for wordpress (bad-behavior-wordpress.php) looked like:

<?php
/*
Plugin Name: Bad Behavior
Version: 2.2.3
Description: Deny automated spambots access to your PHP-based Web site.
Plugin URI: http://bad-behavior.ioerror.us/
Author: Michael Hampton
Author URI: http://bad-behavior.ioerror.us/
License: LGPLv3

Bad Behavior - detects and blocks unwanted Web accesses
Copyright (C) 2005,2006,2007,2008,2009,2010,2011,2012 Michael Hampton

Bad Behavior is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option) any
later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.

Please report any problems to bad . bots AT ioerror DOT us
http://www.bad-behavior.ioerror.us/
*/

###############################################################################
###############################################################################

if (!defined('ABSPATH')) die("No cheating!");

global $bb2_result;

$bb2_mtime = explode(" ", microtime());
$bb2_timer_start = $bb2_mtime[1] + $bb2_mtime[0];

define('BB2_CWD', dirname(__FILE__));

// Bad Behavior callback functions.
require_once("bad-behavior-mysql.php");

// Return current time in the format preferred by your database.
function bb2_db_date() {
	return get_gmt_from_date(current_time('mysql'));
}

// Return affected rows from most recent query.
function bb2_db_affected_rows() {
	global $wpdb;

	return $wpdb->rows_affected;
}

// Escape a string for database usage
function bb2_db_escape($string) {
	global $wpdb;

	return $wpdb->escape($string);
}

// Return the number of rows in a particular query.
function bb2_db_num_rows($result) {
	if ($result !== FALSE)
			return count($result);
	return 0;
}

// Run a query and return the results, if any.
// Should return FALSE if an error occurred.
// Bad Behavior will use the return value here in other callbacks.
function bb2_db_query($query) {
	global $wpdb;

	$wpdb->hide_errors();
	$result = $wpdb->get_results($query, ARRAY_A);
	if ( defined('WP_DEBUG') and WP_DEBUG == true )
			$wpdb->show_errors();
	if (mysql_error()) {
			return FALSE;
	}
	return $result;
}

// Return all rows in a particular query.
// Should contain an array of all rows generated by calling mysql_fetch_assoc()
// or equivalent and appending the result of each call to an array.
// For WP this is pretty much a no-op.
function bb2_db_rows($result) {
	return $result;
}

// Return emergency contact email address.
function bb2_email() {
	return get_bloginfo('admin_email');
}

// retrieve whitelist
function bb2_read_whitelist() {
	return get_option('bad_behavior_whitelist');
}

// retrieve settings from database
function bb2_read_settings() {
	global $wpdb;

	// Add in default settings when they aren't yet present in WP
	$settings = get_option('bad_behavior_settings');
	if (!$settings) $settings = array();
	return array_merge(array('log_table' => $wpdb->prefix . 'bad_behavior', 'display_stats' => true, 'strict' => false, 'verbose' => false, 'logging' => true, 'httpbl_key' => '', 'httpbl_threat' => '25', 'httpbl_maxage' => '30', 'offsite_forms' => false, 'reverse_proxy' => false, 'reverse_proxy_header' => 'X-Forwarded-For', 'reverse_proxy_addresses' => array(),), $settings);

}

// write settings to database
function bb2_write_settings($settings) {
	update_option('bad_behavior_settings', $settings);
}

// installation
function bb2_install() {
	$settings = bb2_read_settings();
	if (!$settings['logging']) return;
	bb2_db_query(bb2_table_structure($settings['log_table']));
}

// Cute timer display; screener
function bb2_insert_head() {
	global $bb2_timer_total;
	global $bb2_javascript;
	echo "\n<!-- Bad Behavior " . BB2_VERSION . " run time: " . number_format(1000 * $bb2_timer_total, 3) . " ms -->\n";
	echo $bb2_javascript;
}

function bb2_approved_callback($settings, $package) {
	global $bb2_package;

	// Save package for possible later use
	$bb2_package = $package;
}

// Capture missed spam and log it
function bb2_capture_spam($id, $comment) {
	global $bb2_package;

	// Capture only spam
	if ('spam' != $comment->comment_approved) return;

	// Don't capture if HTTP request no longer active
	if (array_key_exists("request_entity", $bb2_package) && array_key_exists("author", $bb2_package['request_entity']) && $bb2_package['request_entity']['author'] == $comment->comment_author) {
			bb2_db_query(bb2_insert(bb2_read_settings(), $bb2_package, "00000000"));
	}
}

// Display stats?
function bb2_insert_stats($force = false) {
	global $bb2_result;

	$settings = bb2_read_settings();

	if ($force || $settings['display_stats']) {
			$blocked = bb2_db_query("SELECT COUNT(*) FROM " . $settings['log_table'] . " WHERE `key` NOT LIKE '00000000'");
			if ($blocked !== FALSE) {
					echo sprintf('<p><a href="http://www.bad-behavior.ioerror.us/">%1$s</a> %2$s <strong>%3$s</strong> %4$s</p>', __('Bad Behavior'), __('has blocked'), $blocked[0]["COUNT(*)"], __('access attempts in the last 7 days.'));
			}
	}
	if (@!empty($bb2_result)) {
			echo sprintf("\n<!-- Bad Behavior result was %s! This request would have been blocked. -->\n", $bb2_result);
			unset($bb2_result);
	}
}

// Return the top-level relative path of wherever we are (for cookies)
function bb2_relative_path() {
	$url = parse_url(get_bloginfo('url'));
	if (array_key_exists('path', $url)) {
			return $url['path'] . '/';
	}
	return '/';
}

// FIXME: figure out what's wrong on 2.0 that this doesn't work
// register_activation_hook(__FILE__, 'bb2_install');
//add_action('activate_bb2/bad-behavior-wordpress.php', 'bb2_install');
add_action('wp_head', 'bb2_insert_head');
add_action('wp_footer', 'bb2_insert_stats');
add_action('wp_insert_comment', 'bb2_capture_spam', 99, 2);

// Calls inward to Bad Behavor itself.
require_once(BB2_CWD . "/bad-behavior/core.inc.php");
bb2_install();  // FIXME: see above

if (is_admin() || strstr($_SERVER['PHP_SELF'], 'wp-admin/')) {  // 1.5 kludge
	#wp_enqueue_script("admin-forms");
	require_once(BB2_CWD . "/bad-behavior-wordpress-admin.php");
}

$bb2_result = bb2_start(bb2_read_settings());

$bb2_mtime = explode(" ", microtime());
$bb2_timer_stop = $bb2_mtime[1] + $bb2_mtime[0];
$bb2_timer_total = $bb2_timer_stop - $bb2_timer_start;

Thanks in advance!

Link to comment
Share on other sites

In the WP example, they are getting the DB by making $wpdb a global. In ProcessWire, you'll want to access the database with wire('db'). So you could do something like this:

function bb2_db_escape($string) {
   return wire('db')->escape_string($string); 
}

or this

function bb2_db_escape($string) {
   $db = wire('db'); 
   return $db->escape_string($string); 
}

I don't know what DB library/client WordPress is using, but ProcessWire is using PHP MySQLi. So when you reference wire('db'), you are actually referencing a PHP mysqli object. http://php.net/manual/en/book.mysqli.php

I am guessing that if there were any other ready-to-go bad-behavior-generic files from another CMS that also used mysqli, the implementation would be nearly identical. Please let us know what you find.

Link to comment
Share on other sites

if anyone knows if any of these use mysqli, that would be helpful:

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...