<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
// BotBanish 9.0.05
// Randem Systems: https://randemsystems.support
// BotBanish Contact Form SPAM Denial
// Date: 08/08/2026
//
// Function: Deny SPAM Messages
//
///////////////////////////////////////////////////////////////////////////////////////////////////////

define('LOGIT', true);

function BotBanishContactProcessingActive() {

	global $BotBanishSettings;
	
	if (isset($BotBanishSettings['BOTBANISH_CONTACT_LOCKOUT_ACTIVE']) && $BotBanishSettings['BOTBANISH_CONTACT_LOCKOUT_ACTIVE'])
		
		return true;
	else
		return false;
}

function BotBanishValidateContact_SMF(&$subject, &$message, &$headers, &$to_array) {

	if (!BotBanishContactProcessingActive()) return;
	
	global $BotBanishSettings;
	
	$args = array('subject' => $subject, 'message' => $message, 'headers' => $headers, 'to' => $to_array);
	$action = array('terminate' => false, 'error' => '', 'args' => $args);

	if (BotBanishCheckForExcluded($subject))
		return;

	$tags = BotBanishFixExplode(',', $BotBanishSettings['BOTBANISH_CONTACT_TAGS']);
	$msg = BotBanishRemoveMessageTags($message, $tags);

	if (!isset($msg[0]) || empty($msg[0])) {

		BotBanishContactLogMessages($msg, 'Invalid Message', 'Invalid', LOGIT);
		BotBanishContactLogMessages($subject, 'Original Subject', 'Invalid', LOGIT);
		BotBanishContactLogMessages($message, 'Original Message', 'Invalid', LOGIT);
		return;
	}

	$formIdentifier = trim($msg[0]);

	$action = BotBanishValidateContact($args, $formIdentifier);

	if (isset($action['terminate'])	&& $action['terminate']) {

		$subject = '';
		$message = '';
		$headers = '';
		$to_array = array();
	}
}

function BotBanishValidateContact_WORDPRESS_Pre($ret, $args) {

	if (!BotBanishContactProcessingActive()) return $ret;
	
	$subject = isset($args['subject']) ? $args['subject'] : '';
//	$message = isset($args['message']) ? $args['message'] : '';

	if (!BotBanishCheckForExcluded($subject)) {

		$action = BotBanishValidateContact($args, $subject );

		if (isset($action['terminate']) && $action['terminate'])
			return false;
	}
	
//	BotBanishSendMail($subject, $message);
	return $ret;
}

function BotBanishValidateContact($orig_args, $formIdentifier) {

	global $BotBanishSettings;

	require_once $BotBanishSettings['BOTBANISH_SUBS_DIR'] . 'BotBanish_Subs_Log.php';
	require_once $BotBanishSettings['BOTBANISH_SUBS_DIR'] . 'BotBanish_Subs_Email.php';

	BotBanishContactLogMessages($orig_args, 'Contact Original Message', 'Message', LOGIT);
	$ip = BotBanishGetIP();
	$BotBanishSession = BotBanishGetSession();
	
	if (!empty($BotBanishSession->getSessionKey('locked')))
		BotBanishRedirectExit($BotBanishSettings['BOTBANISH_CONTACT_LOCKOUT']);

	$action = array('terminate' => false, 'error' => '', 'args' => $orig_args);
	if (!BotBanishIsActive()) return $action;

	$args = BotBanishArrayKey_strtolower($orig_args);

	$contact_subject = isset($args['subject']) ? $args['subject'] : '';
	$contact_message = isset($args['message']) ? $args['message'] : '';

	$tags = BotBanishFixExplode(',', $BotBanishSettings['BOTBANISH_CONTACT_TAGS'] . ', Reply-To, Content-Type, X-WPCF7-Content-Type');
	if (isset($tags['Message'])) unset($tags['Message']);

	BotBanishContactLearning($contact_subject, $contact_message, $tags, $formIdentifier);

	if (BotBanishCheckForBadIP($ip)) {

		$action['terminate'] = true;
		return $action;
	}
	
	if (BotBanishCheckForBadIP($ip)) 
		return $action;

	// If the form name is not in our list of form names to process, Leave it alone!

	$str = BotBanishFixItem('"', $formIdentifier);
	$formIdentifier = addslashes($str[0]);

	$formNames_array = BotBanishFixFormIdentifiers();

	if (!in_array($formIdentifier, $formNames_array)) return $action;


	$blocked_country_codes = BotBanishGetBlockedCountryCodes();
	$country_info = BotBanishGetCountryInfo($ip);

	if (in_array($country_info['country_code'], $blocked_country_codes)) {

		$action['terminate'] = true;
		$action['error'] = 'Client Blocked Country';
		BotBanishContactTrace($action, 'Country Check', 'Country', LOGIT);
		BotBanishRejectMessage($orig_args, $action, array());
	}

	$useragent = BotBanishGetUserAgent($_SERVER);
	$useragent = BotBanishFixUserAgent($useragent); // Try to convert and remove extraneous information
	$domain_name = BotBanishGetDomainName($_SERVER);

	$row = array(
				'action' => 'spamcheck',
				'apikey' => isset($BotBanishSettings['BOTBANISH_APIKEY']) ? $BotBanishSettings['BOTBANISH_APIKEY'] : 'Free',
				'version' => $BotBanishSettings['BOTBANISH_VERSION'],
				'version_no' => $BotBanishSettings['BOTBANISH_VERSION_NO'],
				'BOTBANISH_CONTACT_ELIMINATE' => $BotBanishSettings['BOTBANISH_CONTACT_ELIMINATE'],
				'BOTBANISH_CONTACT_FORBIDDEN' => $BotBanishSettings['BOTBANISH_CONTACT_FORBIDDEN'],
				'BOTBANISH_CONTACT_TAGS' => $BotBanishSettings['BOTBANISH_CONTACT_TAGS'],
				'BOTBANISH_CONTACT_REQUIRED' => $BotBanishSettings['BOTBANISH_CONTACT_REQUIRED'],
				'args' => $orig_args,
				'system' => BotBanishCheckSystem(),
				'bot_ip' => $ip,
				'useragent' => $useragent,
				'domain_name' => $domain_name,
				'domain' => BotBanishGetDomainOrigin($ip),
				'ip_addr' => $_SERVER['SERVER_ADDR'],
				'country_codes' => $blocked_country_codes,
				'contact' => isset($BotBanishSettings['BOTBANISH_WEBMASTER_EMAIL']) ? $BotBanishSettings['BOTBANISH_WEBMASTER_EMAIL'] : '',
			);

	$action = BotBanishCheckContact($row);

	if (isset($action['terminate'])) {
		
		if ($action['terminate']) {

			BotBanishRejectMessage($orig_args, $action, $row);

		} else {

			BotBanishContactLogMessages($action, 'Good Message', 'Message', LOGIT);
			
			if (isset($action['country_info']))
				$BotBanishSession->setSessionKey('country_info', $action['country_info']);
		}
		
	} else {
		
		if (isset($action['headers'])) {

			BotBanishContactLogMessages($action, 'Server Error:', 'Error', LOGIT);

		} else {

			BotBanishContactLogMessages($action, 'Missing Action Information (action)', 'Error', LOGIT);
			BotBanishContactLogMessages($row, 'Missing Action Information (row)', 'Error', LOGIT);
			BotBanishContactLogMessages($_SERVER, 'Missing Action Information ($_SERVER)', 'Error', LOGIT);
		}
	} 
	
	return $action;
}

function BotBanishCheckForExcluded($contact_subject) {

	global $BotBanishSettings;

	// if this is a message from an excluded source, leave it be

	$excludes = BotBanishFixExplode(',', $BotBanishSettings['BOTBANISH_CONTACT_EXCLUDE']);

	foreach ($excludes as $exclude) {

		if (stripos($contact_subject, $exclude) !== false) {

//			BotBanishContactLogMessages($contact_subject, 'BotBanishCheckForExcluded()', 'Excluded', true);
			return true;
		}
	}

	return false;
}

function BotBanishContactLogMessages($args, $error, $filetype = '', $logit = false) {

	if (!$logit) return;
	
	$ip = BotBanishGetIP();
	if (BotBanishLimitLogs($ip)) return;
	
	$msg = var_export($args, true) . PHP_EOL . str_repeat('-', 80) . PHP_EOL;
	$msg = str_ireplace(array('<br>', '<br/>','</br>'), PHP_EOL, $msg);

	$filetype = empty($filetype) ? 'Email' : $filetype;
	$filename = BotBanishSetLogFilename($filetype);
	$str = PHP_EOL . PHP_EOL . str_repeat('=', 80) . PHP_EOL;
	$date = BotBanishGetCorrectDateTime();

	global $BotBanishSettings;

	$str = $date . ' - ' . $str . $BotBanishSettings['BOTBANISH_FONT_RED_START'] . BotBanishGetCorrectDateTime() . ' - ' . $error . ' - IP: ' . $ip . $BotBanishSettings['BOTBANISH_FONT_RED_END'] . PHP_EOL . PHP_EOL . $msg;
	
//	BotBanishWriteFile($filename, $str, true);
	BotBanishTraceIt('BotBanishContactTrace - Start - $str', $str, true);
}

function BotBanishContactTrace($rtn, $params, $data, $all = false, $logit = false) {

	if (!$logit) return;

	$ip = BotBanishGetIP();
	if (BotBanishLimitLogs($ip)) return;
	
	$filename = BotBanishSetLogFilename('Trace');
	$date = BotBanishGetCorrectDateTime();

	global $BotBanishSettings;
	
	if ($all) {

		$msg_1 = var_export($params, true) . PHP_EOL . str_repeat('-', 80) . PHP_EOL;
		$msg_1 = str_ireplace(array('<br>', '<br/>','</br>'), PHP_EOL, $msg_1);

		$msg_2 = var_export($data, true) . PHP_EOL . str_repeat('-', 80) . PHP_EOL;
		$msg_2 = str_ireplace(array('<br>', '<br/>','</br>'), PHP_EOL, $msg_2);

		$str = PHP_EOL . PHP_EOL . str_repeat('=', 80) . PHP_EOL;
		$str = $date . ' - ' . $str . $BotBanishSettings['BOTBANISH_FONT_RED_START'] . BotBanishGetCorrectDateTime() . ' - ' . $rtn . ' - IP: ' . $ip . $BotBanishSettings['BOTBANISH_FONT_RED_END'] . PHP_EOL . PHP_EOL . $msg_1 . $msg_2;

	} else {

		$str = $date . ' - ' . $rtn . ' - Row: ' . PHP_EOL . var_export($data, true) . PHP_EOL;
//		BotBanishWriteFile($filename, $str, true);
	}
	
	BotBanishTraceIt('BotBanishContactTrace - Start - $str', $str, true);
}

function BotBanishContactLockOut() {

	global $BotBanishSettings, $BotBanishSession;

	$ip = BotBanishGetIP();

	$useragent = BotBanishGetUserAgent($_SERVER);
	$useragent = BotBanishFixUserAgent($useragent); // Try to convert and remove extraneous information
	$date = BotBanishGetCorrectDateTimeB();

	$row = array();
	$row['bot_ip'] = $ip;
	$row['user_agent'] = $useragent;
	$row['forcelockout'] = $BotBanishSettings['BOTBANISH_CONTACT_LOCKOUT'];
	$row['domain_name'] = BotBanishGetDomainName($_SERVER);
	$row['domain'] = BotBanishGetDomainOrigin($ip);

	BotBanishHTACCESSUpdate($row, 'ip');
	BotBanishInsertLocal($row);		// Update local IP Database
	BotBanishRedirectExit($BotBanishSettings['BOTBANISH_CONTACT_LOCKOUT']);
}

 function BotBanishRejectMessage($args, $action, $row){

	global $BotBanishSettings;
	
	BotBanishContactLogMessages(array($args, $row), $action['error'], 'Reject', LOGIT);
	BotBanishContactLockOut();

	// Attempt to reload current page so that it can redirect to Google

	BotBanishRedirectExit($BotBanishSettings['BOTBANISH_CONTACT_LOCKOUT']);
}

function BotBanishContactLearning($subject, $message, $tags, &$formIdentifier) {

	global $BotBanishSettings;

	if (!isset($BotBanishSettings['BOTBANISH_CONTACT_LEARNING_ACTIVE']) || (empty($BotBanishSettings['BOTBANISH_CONTACT_LEARNING_ACTIVE'])))
		return false;

	BotBanishContactTrace('BotBanishContactLearning($subject, $message)', $subject, $message, false, LOGIT);

	// Setup contact page so that we can intercept emails

	$processed = false;

	switch ($BotBanishSettings['BOTBANISH_SYSTEM']) {

		case 'WORDPRESS':

			$option = get_option('botbanishfirewall_client_option_name');

			if (isset($option['_botbanishtext_botbanish_contact_form'])) {

				if (isset($option['_botbanishtext_botbanish_contact_learning_active']) && $option['_botbanishtext_botbanish_contact_learning_active']) {

					$formName_part = explode('"', $subject);
					$arr = BotBanishFixExplode(',', $option['_botbanishtext_botbanish_contact_form'] . ', ' . $formName_part[0]);
					$new_formName = implode(', ', $arr);

					BotBanishDefineGlobals('BOTBANISH_CONTACT_FORM', $new_formName);
					BotBanishDefineGlobals('BOTBANISH_CONTACT_LEARNING_ACTIVE', 0);
					BotBanishDefineGlobals('BOTBANISH_CONTACT_LOCKOUT_ACTIVE', 1);
					BotBanishSettingsTablePutValues($BotBanishSettings);
					$formIdentifier = $new_formName;

					$option['_botbanishtext_botbanish_contact_learning_active'] = false;
					$option['_botbanishtext_botbanish_contact_form'] = $new_formName;
					update_option('botbanishfirewall_client_option_name', $option);
					$processed = true;
				}
			}

			break;

		case 'SMF':

			if ($BotBanishSettings['BOTBANISH_CONTACT_LEARNING_ACTIVE']) {

				global $mbname;
				
				$arr = BotBanishFixFormIdentifiers();
				$arr[count($arr)] = $subject;
				$arr[count($arr)] = 'Welcome to ' . $mbname;
				$arr = array_map('trim', $arr);
				$arr = array_unique($arr);
				$arr = array_filter($arr);

				$new_formName = implode(', ', $arr);

				BotBanishDefineGlobals('BOTBANISH_CONTACT_FORM', $new_formName);
				BotBanishDefineGlobals('BOTBANISH_CONTACT_LEARNING_ACTIVE', 0);
				BotBanishDefineGlobals('BOTBANISH_CONTACT_LOCKOUT_ACTIVE', 1);
				BotBanishSettingsTablePutValues($BotBanishSettings);
				$formIdentifier = $new_formName;
				$processed = true;
			}

			break;

		default:
			break;
	}

	return $processed;
}

function BotBanishFixFormIdentifiers($formNames = '') {
	global $BotBanishSettings;

	$formNames = empty($formNames) ? $BotBanishSettings['BOTBANISH_CONTACT_FORM'] : $formNames;
	$arr = BotBanishFixExplode(',', $formNames);
	$arr = array_map('addslashes', $arr);
	return $arr;
}

function BotBanishFixMessageIdentifiers($message = '') {

	global $BotBanishSettings;

	$message = empty($message) ? $BotBanishSettings['BOTBANISH_CONTACT_FORM'] : $message;
	$arr = BotBanishFixExplode(PHP_EOL, $message);
	return $arr;
}

function BotBanishFixItem($delimiter, $item) {

	$arr = BotBanishFixExplode($delimiter, $item);
	return $arr;
}

function BotBanishArrayKey_strtolower($arr) {

	$new_arr = array();

	foreach ($arr as $key => $value)
		$new_arr[strtolower($key)] = $value;

	return $new_arr;
}

function BotBanishGetBlockedCountryCodes() {

	$table = 'botbanish_country_code';
	$sql = 'SELECT `country_code` FROM `' . $table . '` WHERE `active` = 1';
	$rows = BotBanishExecuteSQL($sql);
	$newrows = array();

	foreach ($rows as $row)
		$newrows[$row['country_code']] = $row['country_code'];

	return $newrows;
}

function BotBanishRemoveMessageTags($message, $tags) {

	// Remove all tags from the message area

	$remove = array('Reply-To', 'Content-Type', 'Message', 'IP');
	$remove = array_merge ($tags, $remove);
	$msg = explode("\n", $message);

	$arr = array();

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

		if (empty($value))
			continue;

		foreach ($tags as $tag) {

			$tag = trim($tag);
			$tag_key = $tag . ':';

			if (stripos($value, $tag_key ) !== false) {

				unset ($msg[$key]);
				continue;
			}
		}
	}

	return $msg;
}

function BotBanishContactCheckForBlockedCountry($country_info, $blocked_country_codes) {

	// Lets try the easy one first. If the last part of the email is 2 characters it may be the country code

	$info = explode('.', $email);
	$cc = strtolower($info[count($info) - 1]);
	$len = strlen($cc);

	if ($len !== 2) {

		$info = explode('@', $email);
		$dn = $info[count($info) - 1];

		if (function_exists('geoip_country_code_by_name'))

			$cc = geoip_country_code_by_name($dn);
		else
			return false;
	}

	// Look for a blocked counytry from the domain name

	if ((!empty($cc) && strlen(trim($cc)) === 2)) {

		if (in_array($cc, $country_codes))

			return true;
		else
			return false;

	} else {

		return false;
	}
}
?>