<?php
   /*
   Plugin Name: BotBanish Firewall Client
   Plugin URI: https://botbanish.com
   description: A firewall to detect and eliminate bots, users and spiders that are attempting to do harm to your system performing brute force attacks, attempt to create accounts or probing for vulerabilities on your site. We Don't Report Abuse - WE STOP IT!!!
   Version: 9.0.02
   Tested up to: 7.0
   Author: Randem Systems
   Author URI: https://randemsystems.com
   License: GPL2
   */

/*
	// Data to be placed into wp_config.php if needed

// Delete all data for WooCommerce
//define('WC_DELETE_ALL_DATA', true);

// Debug WordPress

if (!defined('WP_DEBUG')) define('WP_DEBUG', true);
if (!defined('WP_CACHE')) define('WP_CACHE', false);
if (!defined('WP_DEBUG_LOG')) define('WP_DEBUG_LOG', true);
if (!defined('WP_DEBUG_DISPLAY')) define('WP_DEBUG_DISPLAY', false);

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting( E_ALL && ~E_NOTICE && ~E_DEPRECATED );
*/
	// Changed: 07/18/2026 - Added Database Update routines for WordPress updates.
	// Changed: 10/07/2025 - Added Core and Theme Audits.
	// Changed: 09/26/2025 - Added Plugin Audit.
	// Changed: 01/02/2025 - Improved backup and import capabilities.
	// Changed: 12/23/2024 - Added contact Messge Tags.
	// Changed: 12/22/2024 - Added contact excludes.
	// Changed: 11/11/2024 - Delete settings files on activation.
	// Changed: 11/06/2024 - Addedd css to page headers
	// Changed: 10/30/2024 - Fixed BOTBANISH_DIR to remove double slash
	// Changed: 07/12/2024 - Correct BotBanish_ValidateContact().
	// Changed: 05/30/2024 - Added new checks to BotBanish_ValidateContact().
	// Changed: 05/10/2024 - Fixed data delete issue.
	// Changed: 05/10/2024 - Check contact information from contact forms or outgoing mail.
	// Changed: 05/04/2024 - Uninstall not to delete BotBanish database tables unless chosen to do so.
	// Changed: 03/16/2024 - Added system name to analytics log call.
	// Changed: 03/14/2024 - Change database backup to table based backup.
	// Changed: 07/05/2023 - Added wp-config.php and .htaccess protection option
	// Changed: 06/25/2023 - Added xmlrpc.php protection option
	//						 Changed startup flow
	// Changed: 06/16/2023 - Added filter to check login attempts
	// Changed: 05/19/2023 - Added download of documents at install time that cannot fit into the install
	// Changed: 05/05/2023 - Do not uninstall html info, write log if uninstalling
	// Changed: 02/21/2023 - Added routine to add and update country and country_code fields to database tables
	// Changed: 11/15/2022 - Copied Analytics status and css folder to wp-content/themes/BotBanish folder. Added delete data option.
	// Changed: 11/13/2022 - Remove copying BotBanish to root. Remove BotBanish echo code in wp_head
	// Changed: 09/17/2022 - Fix setting not having defaults
	// Changed: 09/15/2022 - Copy the BotBanish folder to the WordPress root so that Analytics can save data

	require_once plugin_dir_path( __FILE__ ) . 'BotBanish_DB_Update.php';

	$request_types = array('GET', 'POST');

	$diag = 0;
	$ip_hit_count = 0;
	$ip_first_hit = 0;
	$client_info = array();
	$user_id = '';
	$BotBanishText = array();
	$BotBanishSettings = array();
	$debugtracerow = array();
	$country_info = array();
	$conn = '';

	$BotBanishSQL = '';
	$BotBanishURL = '';
	$BotBanishConn = '';
	$BotBanishTableColumns = array();

	define('BOTBANISH_MINIMUM_WP_VERSION', '6.0' );
	define('BOTBANISH_PLUGIN_DIR', str_ireplace('\\', '/', rtrim(plugin_dir_path( __FILE__ ), '/') . '/'));
	define('BOTBANISH_PLUGIN_URL', plugin_dir_url(__FILE__));
	define('BOTBANISH_DIR', BOTBANISH_PLUGIN_DIR . 'bot/');
	define('BOTBANISH_STATIC_DIR', ABSPATH . 'wp-content' . '/BotBanish_Data/');

//	define('BOTBANISH_CLIENT_DEBUG', true);
	
	BotBanish_Start();
	BotBanishMaitainUserTables();

function BotBanish_plugin_activation() {

	global $BotBanishSettings;

	define('BOTBANISH_INSTALL', 1);
	define('BOTBANISH_INSTALL_TYPE', 'Client');

	$BotBanishSettings['BOTBANISH_INSTALL'] = 1;

	require_once BOTBANISH_PLUGIN_DIR . 'bot/Subs/BotBanishInstall.php';

	BotBanish_InitializeDefaults();

	BotBanishLoadPluginAudit();

	add_option('BotBanish_do_activation_redirect', true);
}

function BotBanish_plugin_deactivation() {

	global $BotBanishSettings;

	// Remove all our custom actions& Filters

	define('BOTBANISH_UNINSTALL', 1);
	BotBanishDeactivateFilters();
	BotBanishDeactivateActions();

	BotBanishLoadSettings();

	$options = get_option('botbanishfirewall_client_option_name', false);
	$deletedata = isset($options['_botbanishtext_botbanish_delete_data']) ? boolval($options['_botbanishtext_botbanish_delete_data']) : false;

	$_POST['system'] = 'wordpress';
	$_POST['delete'] = $deletedata;
	$_POST['silent'] = true;
	$_POST['internal'] = true;
	
	// For debugging only
//	error_reporting(E_ALL);
	
	require_once $BotBanishSettings['BOTBANISH_SUBS_DIR'] . 'BotBanishCleanup/BotBanishInstallCleanup.php';
}

function BotBanish_CheckDebugLogStatus() {

	global $BotBanishSettings;

	// This had to be done for the INTECH themes and other themes that use the redux-framework.
	// They create a lot of depreaciation warnings in PHP 8.x in the
	// PHP error.log and WordPress debug.log files which at some point will overrun the hosting domain's storage.

	if (!isset($BotBanishSettings['BOTBANISH_DB_NAME']))
		return;

	if (defined('WP_DEBUG') && WP_DEBUG) {

		$count = BotBanishGetSessionInfo('BOTBANISH_DEBUG_COUNT');
		if (empty($count)) $count = 0;

		if ($count > 100) {

			$filenames = array(ABSPATH . 'error_log', $_SERVER['HOME'] . '/logs/' . str_ireplace(".", "_", BotBanishGetDomainName($_SERVER)) . 'php.error.log');

			foreach ($filenames as $filename) {

				clearstatcache();

				if (file_exists($filename) && (filesize($filename) > (1024 * 125)))
					unlink($filename);
			}

			BotBanishSetSessionInfo('BOTBANISH_DEBUG_COUNT', 1);

		} else {

			$count++;
			BotBanishSetSessionInfo('BOTBANISH_DEBUG_COUNT', $count);
		}
	}
}

function BotBanish_Start() {

	BotBanishLoadSettings();
}

function BotBanishCleanUpFiles() {

	global $BotBanishSettings;

	// Cleanup files that may have been left behind on a incomplete install

	$files = array(
		'BotBanish_RegisterAccount.html',
		'BotBanish_RegisterAccount.php',
		'Settings_Client.php',
		'BotBanish_Settings.php',
		);

	foreach ($files as $filename) {

		if (file_exists($BotBanishSettings['BOTBANISH_DIR'] . $filename))
			unlink($BotBanishSettings['BOTBANISH_DIR'] . $filename);
	}
}

function BotBanishLoadSettings() {

	global $BotBanishSettings;

	if (!defined('BOTBANISH_PLUGIN_DIR'))
		define('BOTBANISH_PLUGIN_DIR', str_ireplace('\\', '/', rtrim(plugin_dir_path( __FILE__ ), '/') . '/'));

	BotBanishLoadFunctions();

	if (file_exists(BOTBANISH_PLUGIN_DIR . 'bot/Settings_Client.php'))

		BotBanishGetOptions();
	else
		delete_option('botbanishfirewall_client_option_name');

}

function BotBanishLoadFunctions () {

	global $BotBanishSettings;
	
	if (!function_exists('BotBanishSetSessionInfo'))
		require_once BOTBANISH_PLUGIN_DIR . 'bot/Include/BotBanish_PreIncludes.php';
}

function BotBanishGetOptions() {

	require_once BOTBANISH_PLUGIN_DIR . 'BotBanish_Options.php';
	require_once ABSPATH . 'wp-admin/includes/plugin.php';

	if (is_plugin_active(BotBanishGetOurPluginName()))
		BotBanish_InitializeDefaults();
}

function BotBanishGetOurPluginName() {
	
	$plugin_data = get_plugin_data( __FILE__ );
	$plugin_name = $plugin_data['Name'] . '/' . basename(__FILE__);
	return $plugin_name;
}

function BotBanish_InitializeDefaults() {

	global $BotBanishSettings;

	if (isset($BotBanishSettings['BOTBANISH_INSTALL']) && $BotBanishSettings['BOTBANISH_INSTALL']) {

		delete_option('botbanishfirewall_client_option_name');
		$options = array();

	} else {

		$options = get_option('botbanishfirewall_client_option_name', false);
	}

	if (empty($options)) {

		require_once BOTBANISH_PLUGIN_DIR . 'BotBanish_Options.php';
		$botbanishfirewall_client_options = new BotBanishFirewallClientOptions();
		$info = $botbanishfirewall_client_options->info;

		foreach ($info as $key => $value) {

			$name = $value['name'];
			$options[$key] = isset($BotBanishSettings[$name]) ? $BotBanishSettings[$name] : '';
		}

		add_option('botbanishfirewall_client_option_name', $options, '' ,'no');
	}
}

function BotBanishClientPageStart() {

	BotBanishLoadSettings();

	if (BotBanishIsAdmin())
		return;

	BotBanishTraceIt('BotBanishClientPageStart - Start:', '1st', false);

	BotBanishIsUserLockedOut();	// will not return if user is locked out

	BotBanishTraceIt('BotBanishClientPageStart - End:', '2nd', false);

	BotBanishClientAnalytics();
}

function BotBanishUserCheck() {

	$user_obj = wp_get_current_user();

	BotBanishTraceIt('BotBanishUserCheck - Start: - $user_obj', $user_obj, false);

	if ((isset($user_obj->ID)) || ($user_obj->ID == 0)) {

		$verified = (BotBanishGetSessionInfo('verified') == 'Yes') ? true : false;;
		if (!$verified) BotBanishClient();
	}
}

function BotBanishClientAnalytics() {

	global $BotBanishSettings;

	if (!defined('BOTBANISH_PLUGIN_DIR'))
		define('BOTBANISH_PLUGIN_DIR', str_ireplace('\\', '/', rtrim(plugin_dir_path( __FILE__ ), '/') . '/'));

	$pagename = get_the_title();

	BotBanishTraceIt('BotBanishClientAnalytics - Start: - $pagename', $pagename, false);

	// If there is no page name, we can do nothing here!

	if (empty($pagename))
		return;

	$_GET['pagename'] = $pagename;
	$_GET['system'] = 'WORDPRESS"';
	$_GET['location'] = BOTBANISH_PLUGIN_DIR;
	BotBanishTraceIt('BotBanishClientAnalytics - Start: - $_GET', $_GET, false);
	require_once BOTBANISH_PLUGIN_DIR . 'bot/Analytics/BotBanishAnalyticsLog.php';
}

function BotBanishClientPublishPost($post_id) {

	// When the user clicks the publish button; we check him out

	$user_obj = wp_get_current_user();

	if (isset($user_obj->user_login) && isset($user_obj->user_email))
		BotBanishClient(false, $user_obj->user_login, $user_obj->user_email, false);
}

function BotBanishClientCommentPost($comment_ID, $comment_approved) {

	// if someone is attempting to submit a comment, check them out
	// There is no user signed in so we get it from the comment form post

	if ($_POST['author'] && $_POST['email'])
		BotBanishClient(false, $_POST['author'], $_POST['email'], false);
}

function BotBanishClientNewUserAddField()
{
	// Place our hidden field in the registration form

	?>
		user_name" name="user_name" value="" />
	<?php
}

function BotBanishClientLogin($username, $user_obj) {

	if (BotBanishIsAdmin($user_obj))
		return;

//	$user = wp_get_current_user();

	// Check this user after they log on

	$user_info = array('name' => $user_obj->data->name,
					'username' => $user_obj->data->user_login,
					'display_name' => $user_obj->data->display_name,
					'first' => $user_obj->data->first_name,
					'last' => $user_obj->data->last_name,
					'email' => $user_obj->data->user_email,
					'address' => '',
					'phone' => '',
					'ip' => BotBanishGetIP(),
					'domain' => BotBanishGetDomainName(),
				);

	BotBanishValidateUser($user_info);
}

function BotBanishClientRegister($user_id) {

	$user_obj = get_user_by('id', $user_id);

	if (BotBanishIsAdmin($user_obj))
		return;

	 if (isset($_POST['botname']) && !empty($_POST['botname'])) {

		// Check for our special registration field

		global $BotBanishSettings;
		BotBanishClient($BotBanishSettings['BOTBANISH_HIDDEN_LOCKOUT'], $user_obj->user_login, $user_obj->user_email, false);	// Lock user out

	} else {

		// Check for email field

		$username = $user_obj->data->user_login;
		$email = $user_obj->data->user_email;
		BotBanishClient(false, '', $email, false);
	}
}

function BotBanishClientAddUser($user_id, $notify) {

	$user_obj = get_user_by('id', $user_id);

	if (BotBanishIsAdmin($user_obj))
		return;

	$username = $user_obj->data->user_login;
	$email = $user_obj->data->user_email;

	 if (isset($_POST['botname']) && !empty($_POST['botname'])) {

		// Check for our special registration field

		global $BotBanishSettings;

		BotBanishClient($BotBanishSettings['BOTBANISH_HIDDEN_LOCKOUT'], $username, $email, false);	// Lock user out

	} else {

		BotBanishClient(false, $username, $email, false);	// Will not return if a bad user
	}
}

function BotBanishClientRegisterPost($sanitized_user_login, $user_email, $errors) {

	$user_obj = get_user_by('email', $user_email);

	if (BotBanishIsAdmin($user_obj))
		return;

	// Check the posting user
	$username = $user_obj->data->user_login;
	$email = $user_obj->data->user_email;
	BotBanishClient(false, $sanitized_user_login, $email, false);
}

function BotBanishAuthenticate($user_obj) {

	if (BotBanishIsAdmin($user_obj))
		return;

	// Before user logs into WordPress

	$username = $user_obj->data->user_login;
	$email = $user_obj->data->user_email;

	if (isset($user_obj->data->user_login)){

		BotBanishClient(false, $username, $email, false);	// Check for a bad user logon attempt

	} else {

		if (isset($user_obj->errors['invalid_username'])) {

			global $BotBanishSettings;
			BotBanishClient($BotBanishSettings['BOTBANISH_USER_LOCKOUT'], $user_obj->user_login, $user_obj->user_email, false);	// Lock user out
		}
	}

	return $user_obj;
}

function BotBanish_Authenticate_User( $user ) {

	// Before user logs into WordPress

	BotBanishLoadSettings();
	BotBanishClient(false, '', '', false);	// let's log this login attempt
	return $user;
}

function IsBotBanishActivated() {

	$plugin_name = BotBanishGetOurPluginName();

	if (!is_plugin_active($plugin_name)) 
		return false;
	else
		return true;
}

function BotBanishActivateSister() {

	// When deactivating BotBanish we should try to activate the Contact Form Denial Plugin

	if (!is_plugin_active('Contact-Form-SPAM-Denial/Contact Form SPAM Denial.php'))
        add_action('update_option_active_plugins', 'BotBanish_Activate_Sister', true);
}

function BotBanish_Activate_Sister() {

    activate_plugins('Contact-Form-SPAM-Denial/Contact Form SPAM Denial.php');
}

function BotBanishDeactivateSister() {

	// When activating BotBanish we should try to deactivate the Contact Form Denial Plugin

    if (is_plugin_active('Contact-Form-SPAM-Denial/Contact Form SPAM Denial.php'))
        add_action('update_option_active_plugins', 'BotBanish_Deactivate_Sister', true);
}

function BotBanish_Deactivate_Sister() {

 	deactivate_plugins('Contact-Form-SPAM-Denial/Contact Form SPAM Denial.php');
}

function BotBanish_WordPress_is_admin($user_obj = '') {

	if (!is_object($user_obj))
		$user_obj = wp_get_current_user();

	// If the logged on user is an admin, no need to check anything

	if (!isset($user_obj->roles) && !is_array($user_obj->roles))
		return false;

	return in_array('administrator',  $user_obj->roles);
}

function BotBanish_Redirect() {

	BotBanishLoadFunctions();
	BotBanishRedirectExit();
}

function BotBanishGoToSettings() {

    if (get_option('BotBanish_do_activation_redirect', false)) {

		$options = get_option('botbanishfirewall_client_option_name', false);
        delete_option('BotBanish_do_activation_redirect');

        if (wp_safe_redirect("options-general.php?page=botbanishfirewall-client"))
			exit();
	}
}

function BotBanishLoadPluginAudit() {

	if ( is_admin() ) {

		$options = get_option('botbanishfirewall_client_option_name');

		if (isset($options['_botbanishtext_botbanish_plugin_audit_active']) && $options['_botbanishtext_botbanish_plugin_audit_active']) {

			require_once 'BotBanish_PluginAudit.php';

			// Make sure we record our own activation

			$plugin = str_ireplace('activate_', '', current_filter());
			$auditType = array(
								'plugin' => $plugin,
								'status' => 'activated',
								'msg' => 'BotBanish Activated',
							);

			$BotBanishFirewallPluginAudit = new BotBanishFirewallPluginAudit();
			$BotBanishFirewallPluginAudit->BotBanishRecordAuditStatus('plugin', $auditType);

			return true;
		}
	}

	return false;
}

 function BotBanishSetUserAgent($args, $url) {

	$args['user-agent'] = 'mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.110 safari/537.36';
	return $args;
 }

 function BotBanishSetUserAgentHTTP($useragent) {

	return 'mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/58.0.3029.110 safari/537.36';
 }

 // We must eliminate all accounts that have not activated their account in 24 hours.
 // This is mainly to eliminate bots that attempt to create WordPress accounts with fake emails.
 // Since the emails are fake the accounts will NEVER get activate and will take up space
 // This is will help if the Square plugin is actively syncing data to WooCommerce.
 // For some reason the Square pluging syncs customer data even if the customer has never activated their account,
 // Which makes it impossible for them to have orders or purchases on Square or WooCommerce.

 function BotBanishMaitainUserTables() {

	global $BotBanishSettings;

	if (isset($BotBanishSettings['BOTBANISH_USER_CLEANUP_DAYS']) && isset($BotBanishSettings['BOTBANISH_USER_CLEANUP_TIME'])) {

		$elapsedTime = BotBanishElapsedTime(date("Y-m-d H:i:s"), $BotBanishSettings['BOTBANISH_USER_CLEANUP_TIME']);
		$system = BotBanishCheckSystem();
		$days = $BotBanishSettings['BOTBANISH_USER_CLEANUP_DAYS'];

		// Run once a day

		if ($elapsedTime['days'] > 0) {

			$dbInfo = BotBanishGetDatabaseInfo();

			switch (strtoupper($system['system'])) {

				case 'WORDPRESS':

					$tableWoo = $dbInfo['tblprefix'] . 'wc_customer_lookup';
					$rows = BotBanishGetTableNames($tableWoo);

					if (is_array($rows) && !empty($rows)) {

						$tableWP = $dbInfo['tblprefix'] . 'users';
						$rows = BotBanishGetTableNames($tableWP);

						if (is_array($rows) && !empty($rows)) {

							$sql = 'SELECT `email` FROM `' . $tableWoo .'` WHERE `first_name` = "" AND `last_name` = "" AND DATEDIFF(NOW(), `date_last_active`) > ' . $days;
							$rows = BotBanishExecuteSQL($sql, true, true);

							// Match the fake WooCommerce email to the fake WordPress emails and delete them

							foreach ($rows as $row) {

								$sql = 'DELETE FROM `' . $tableWP . '` WHERE `user_email` = "' . $row['email'] . '"';
								BotBanishExecuteSQL($sql, true, true);

								$sql = 'DELETE FROM `' . $tableWoo . '` WHERE `email` = "' . $row['email'] . '"';
								BotBanishExecuteSQL($sql, true, true);
							}
						}
					}

					break;

				case 'SMF':

					break;

			}

			$BotBanishSettings['BOTBANISH_USER_CLEANUP_TIME'] = date("Y-m-d H:i:s");
		}
	}

	BotBanishSetUserCleanup();
 }

 function BotBanishSetUserCleanup() {

	 global $BotBanishSettings;

	if (!isset($BotBanishSettings['BOTBANISH_USER_CLEANUP_DAYS']))
		$BotBanishSettings['BOTBANISH_USER_CLEANUP_DAYS'] = 1;

	if (!isset($BotBanishSettings['BOTBANISH_USER_CLEANUP_TIME']))
		$BotBanishSettings['BOTBANISH_USER_CLEANUP_TIME'] = date("Y-m-d H:i:s");
 }
 
function BotBanishRedirect404() {
	
	global $BotBanishSettings;
	
   if (is_404()) {
	   
		$_GET['BOTBANISH_REDIRECT_STATUS'] = 404;   
		include $BotBanishSettings['BOTBANISH_SUBS_DIR'] . 'BotBanish_AccessError.php';
   }
}

//===========================================================================
// This runs only at module load time
//===========================================================================

	if ( is_admin() ) {

		$options = get_option('botbanishfirewall_client_option_name');

		if (isset($options['_botbanishtext_botbanish_plugin_audit_active']) && $options['_botbanishtext_botbanish_plugin_audit_active'])
			require_once 'BotBanish_PluginAudit.php';
	}

	register_activation_hook( __FILE__, 'BotBanish_plugin_activation');
	register_deactivation_hook( __FILE__, 'BotBanish_plugin_deactivation');

	// Add all our custom actions & Filters

	require_once BOTBANISH_PLUGIN_DIR . 'BotBanish_Hooks.php';
?>