<?php
/*
Plugin Name:	WP-SpamShield Anti-Malware & Functional Integrity Scanner Module
Plugin URI:		https://www.redsandmarketing.com/plugins/wp-spamshield-anti-spam/
Description:	A module of WP-SpamShield that checks for malicious plugin files and ensures plugin functional integrity. (Required for WP-SpamShield functionality.)
Version:		1.9.41
Author:			Red Sand Media Group and Blackhawk Cybersecurity
Author URI:		https://www.redsandmarketing.com/plugins/wp-spamshield-anti-spam/
Text Domain:	wp-spamshield
Domain Path:	/lang
*/

/**
 *	Anti-Malware & Functional Integrity Scanner Module
 *	Packaged with WP-SpamShield plugin
 *	This module of WP-SpamShield checks for malicious plugin files and ensures plugin functional integrity.
 *	This MU plugin is required for full functionality of WP-SpamShield. Do not disable or delete, as WP-SpamShield manages this as needed.
 *	This will be automatically removed during WP-SpamShield uninstall process.
 *	@since 1.9.20
 */

/* Make sure file remains secure if called directly */
if( !defined( 'ABSPATH' ) ) {
	if( !headers_sent() ) { @header( 'HTTP/1.0 403 Forbidden', TRUE, 403 ); @header( 'X-Robots-Tag: noindex', TRUE ); }
	die( 'ERROR: Direct access to this file is not allowed.' );
}

/* Prevents unintentional error display if WP_DEBUG not enabled. */
if( TRUE !== WP_DEBUG ) { @ini_set( 'display_errors', 0 ); @error_reporting( 0 ); }
add_filter( 'show_advanced_plugins', '__return_false', 10000 );

/* Fix translations, settings, etc. */
add_filter( 'gettext', 'wpss_mu_fix_translations', 999999999, 3 );
add_action( 'muplugins_loaded', 'wpss_mu_fix_options', 999999999 );
add_action( 'activated_plugin', 'wpss_mu_fix_options', 999999999 );
add_action( 'deactivated_plugin', 'wpss_mu_fix_options', 999999999 );
add_action( 'admin_notices', 'wpss_mu_admin_notices', -999999999 );
add_filter( 'plugin_action_links_'.'wp-spamshield/wp-spamshield.php', 'wpss_mu_action_links', 10000, 4 );

/* Fix for WP Engine Incorrectly Caching Plugin JS URLs */
if( defined( 'WPE_APIKEY' ) || defined( 'WPE_PLUGIN_VERSION' ) ) {
	if( !isset( $GLOBALS['wpengine_platform_config'] ) || !is_array( $GLOBALS['wpengine_platform_config'] ) ) {
		$GLOBALS['wpengine_platform_config'] = array( 'no_cdn_uris' => array(), );
	}
	if( !isset( $GLOBALS['wpe_no_cdn_uris'] ) || !is_array( $GLOBALS['wpe_no_cdn_uris'] ) ) {
		$GLOBALS['wpe_no_cdn_uris'] = array();
	}
	if( !isset( $GLOBALS['wpengine_platform_config']['no_cdn_uris'] ) || !is_array( $GLOBALS['wpengine_platform_config']['no_cdn_uris'] ) ) {
		$GLOBALS['wpengine_platform_config']['no_cdn_uris'] = array();
	}
	$GLOBALS['wpengine_platform_config']['no_cdn_uris'][] = $GLOBALS['wpe_no_cdn_uris'][] = 'spamshield';
}

if( !defined( 'WPSS_AMIS_LOADED' ) ) { define( 'WPSS_AMIS_LOADED', TRUE ); }

/**
 *	Allow manual override by admins
 *	Usage -- add one of the following to `wp-config.php`
 *		Enabled (Default):
 *		define( 'WPSS_AMIS_SCAN_DISABLE', FALSE	);
 *		Disabled:
 *		define( 'WPSS_AMIS_SCAN_DISABLE', TRUE	);
 */
if( defined( 'WPSS_AMIS_SCAN_DISABLE' ) && TRUE === WPSS_AMIS_SCAN_DISABLE ) {
	if( !defined( 'WPSS_AMIS_OVERRIDE' ) ) { define( 'WPSS_AMIS_OVERRIDE', TRUE ); }
}


/**
 *	Directories
 */
$mu_files = wpss_mu_scandir( __DIR__ );
$pl_files = wpss_mu_scandir( WP_PLUGIN_DIR );

/**
 *	Malicious Signatures
 *	Scans for fake malware plugin "X-WP-SPAM-SHIELD-PRO" (which is in no way associated with the real WP-SpamShield).
 *	More Info: https://www.redsandmarketing.com/blog/malware-alert-x-wp-spam-shield-pro-fake-plugin/
 */
$mal_keys	= array( 'spam-shield-pro', 'x-wp-spam-shield' );
$mal_dmc	= "~/.*wp\-*spam\-*shield.*/(.*/)*class\.plugin\-modules\.php~i";
$mal_rgx	= "~((x\-*)?wp\-*)?spam\-*shield\-*pro~i";

if(
	( !defined( 'WPSS_AMIS_OVERRIDE' ) || TRUE !== WPSS_AMIS_OVERRIDE )
	&&
	( ( is_admin() || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) || ( !empty( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] ) )
) {
	foreach( $mu_files as $i => $file ) {
		if( $file === basename( __FILE__ ) ) { continue; }
		$path = __DIR__ . DIRECTORY_SEPARATOR . $file;
		foreach( $mal_keys as $i => $k ) {
			if( FALSE !== stripos( $path, $k ) ) {
				if( @is_file( $path ) ) { @chmod( $path, 0310 ); @unlink( $path ); continue 2; }
			}
		}
		if( preg_match( $mal_rgx, $path ) ) {
			if( @is_file( $path ) ) { @chmod( $path, 0310 ); @unlink( $path ); continue; }
		}
		$file_contents = trim( @file_get_contents( $path ) );
		if( !empty( $file_contents ) && FALSE !== strpos( $file_contents, 'wp-spamshield' ) ) { @chmod( $path, 0310 ); @unlink( $path ); continue; }
	}
	foreach( $pl_files as $i => $file ) {
		$path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $file;
		foreach( $mal_keys as $i => $k ) {
			if( FALSE !== stripos( $path, $k ) || preg_match( $mal_rgx, $path ) ) {
				if( @is_file( $path ) ) { @chmod( $path, 0310 ); @unlink( $path ); continue 2; }
				if( @is_dir( $path ) ) { wpss_mu_rmdir_deep( $path ); continue 2; }
			}
		}
		if( preg_match( $mal_dmc, $path ) ) {
			wpss_mu_dmc( 'set' );
			if( @is_file( $path ) ) { @chmod( $path, 0310 ); @unlink( $path ); continue; }
			if( @is_dir( $path ) ) { wpss_mu_rmdir_deep( $path ); continue; }
		}
		if( preg_match( $mal_rgx, $path ) ) {
			if( @is_file( $path ) ) { @chmod( $path, 0310 ); @unlink( $path ); continue; }
			if( @is_dir( $path ) ) { wpss_mu_rmdir_deep( $path ); continue; }
		}
	}

}

/**
 *	Drop-in replacement for PHP function scandir()
 *	Has sanitation and error correction built-in
 *	@dependencies	none
 *	@since			1.9.20
 */
function wpss_mu_scandir( $dir ) {
	if( empty( $dir ) || ! @is_string( $dir ) ) { return $dir; }; @clearstatcache();
	$dot_files	= array( '..', '.' );
	$dir_listr	= (array) @scandir( $dir );
	$dir_list	= array_values( array_diff( $dir_listr, $dot_files ) );
	return $dir_list;
}

/**
 *	Drop-in replacement for PHP function rmdir(), Recursive
 *	@dependencies	none
 *	@since			1.9.20
 */
function wpss_mu_rmdir_deep( $path ) {
	$i = new DirectoryIterator( $path );
	foreach( $i as $f ) {
		if( $f->isFile() ) {
			@unlink( $f->getRealPath() );
		} else if( ! $f->isDot() && $f->isDir() ) {
			wpss_mu_rmdir_deep( $f->getRealPath() );
		}
	}
	@rmdir( $path );
}

/**
 *	Filter the plugin data array in preparation for output to the plugins table.
 *	@dependencies	...
 *	@used by		...
 *	@since			1.9.35
 */
function wpss_mu_filter_plugin_data( $all_plugins ) {
	/**
	 *	$all_plugins = array(
	 *		$plug_bn	=> array( 'Name', 'PluginURI', 'Version', 'Description', 'Author', 'AuthorURI', 'TextDomain', 'DomainPath', 'Network', 'Title', 'AuthorName', )
	 *	);
	 *	$plug_bn	= 'folder/filename.php'; // Plugin Basename
	 */
	$desc =
		array(
			'wp-spamshield/wp-spamshield.php'	=> '<strong>Illegal Pirated/Hacked Software</strong> &mdash; The unauthorized reproduction or distribution of a copyrighted work is illegal. Criminal copyright infringement, including infringement without monetary gain, is investigated by the FBI and other international law enforcement agencies and is punishable by fines and imprisonment. Pirated software ("nulled", "warez", "shared", etc.) is extremely dangerous to use, and almost always contain malware that will compromise your website to hackers. These sites claim to be benevolent, but they exist solely to distribute malware-laden software and hack your website.<br /><br />

			To get a legitimate, legal, and safe copy of this software, you can <a href="https://www.redsandmarketing.com/go/cc/wp-spamshield/" >purchase it here</a>.',
		);
	$mod_plugins = array();
	foreach( $all_plugins as $plug_bn => $plugin_data ) {
		$file = trim( basename( __FILE__ ), DIRECTORY_SEPARATOR );
		$plugin_data['Name'] = ( 'WP-SpamShield Anti-Malware & Functional Integrity Scanner Module' !== $plugin_data['Name'] && ( preg_match( "~^WP\-SpamShield.+~i", $plugin_data['Name'] ) || ( 'WP-SpamShield' === $plugin_data['Name'] && ( empty( $plugin_data['PluginURI'] ) || wpss_mu_dmc() ) ) ) ) ? 'WP-SpamShield [ILLEGAL PIRATED/HACKED COPY]' : $plugin_data['Name'];
		if( FALSE !== strpos( $plug_bn, '/wp-spamshield.php' ) ) { $desc[$plug_bn] = $desc['wp-spamshield/wp-spamshield.php']; }
		if( !empty( $desc[$plug_bn] ) && ( FALSE !== strpos( $plugin_data['Name'], '[ILLEGAL PIRATED/HACKED COPY]' ) || wpss_mu_dmc() ) ) { wpss_mu_dmc( 'set' ); $plugin_data['Description'] = $desc[$plug_bn]; }
		$mod_plugins[$plug_bn] = $plugin_data;
	}
	$all_plugins = $mod_plugins; unset( $plug_bn, $plugin_data, $mod_plugins );
	return $all_plugins;
}
add_filter( 'all_plugins', 'wpss_mu_filter_plugin_data', 999999999 );

/**
 *	DMC Check
 *	Part of detection de boucanier
 *	@dependencies	...
 *	@used by		...
 *	@since			1.9.35
 *	@param			string	$method		'set'|'chk'
 */
function wpss_mu_dmc( $method = 'chk' ) {
	if( 'set' === $method || defined( 'DEAD_MANS_CHEST' ) || ( get_option( 'dead_mans_chest' ) ) ) {
		$dmc = 'Yo-ho-ho, and a bottle of rum!';
		if( !defined( 'DEAD_MANS_CHEST' ) ) { define( 'DEAD_MANS_CHEST', $dmc ); }; update_option( 'dead_mans_chest', $dmc ); return TRUE;
	}
	return FALSE;
}

/**
 *	Fix erroneous option values.
 *	@dependencies	none
 *	@since			1.9.35
 */
function wpss_mu_fix_options() {
	$s = 'antispam'; $t = 'turing'; $h = 'honeypot'; $c = str_replace( array( 'uring', '-r', '-', 'k', ), array( 'cha', '-', '', 'c', ), 'k-rap-' . $t ); $a = str_replace( array( 'untie', 'y', 'me' ), array( '', 'i', 'met' ), 'auntie' . 'kysme' ); $r = 're' . $c; $d = 'disable';

	$fix_options = array( 'PO_' => array( $d.'_compat_notices' => 'one', $d.'_admin_warning' => 'one', $d.'_admin_notices' => 'one', 'display_debug_msg' => 'zero', ), 'gwolle_gb-' => array( $a.'-active' => 'false', $s.'-answer' => '', $s.'-question' => '', 'form_ajax' => 'false', $h => 'false', 'moderate-entries' => 'true', 'nonce' => 'false', ), $a.'_' => array( 'comment_nonce' => 'false', 'spam_count' => 'zero', 'ssl_'.$d.'d' => 'false', ), 'no_pref' => array( $a => '', $c => '', $h => '', $r => '', ), );
	foreach( $fix_options as $pref => $a ) {
		$pref = ( 'no_pref' === $pref ) ? '' : $pref;
		foreach( $a as $k => $v ) {
			$cb = ( '' === $v || NULL === $v ) ? '__return_empty_string' : '__return_'.$v;
			add_filter( 'pre_option_'.$pref.$k, $cb, 100000, 1 );
			add_filter( 'option_'.$pref.$k, $cb, 100000, 1 );
			add_filter( 'pre_update_option_'.$pref.$k, $cb, 100000, 1 );
		}
	}

}

/**
 *	Fixes erroneous text translations.
 *	@dependencies	...
 *	@used by		...
 *	@since			1.9.35
 *	@param			string	$translation	Translated text.
 *	@param			string	$text			Text to translate.
 *	@param			string	$domain			Text domain. Unique identifier for retrieving translated strings.
 */
function wpss_mu_fix_translations( $translation, $text, $domain ) {
	$s = 'antispam'; $t = 'turing'; $h = 'honeypot'; $c = str_replace( array( 'uring', '-r', '-', 'k', ), array( 'cha', '-', '', 'c', ), 'k-rap-' . $t ); $a = str_replace( array( 'untie', 'y', 'me' ), array( '', 'i', 'met' ), 'auntie' . 'kysme' ); $r = 're' . $c;
	$txt_keys	= array( 'wp spamshield', 'spam shield', 'you are not a robot' );
	$dom_keys	= array( 'printful', 'wordpress-seo', $a, );
	$rep_keys	= array();
	$pre_keys	= array();
	$app_keys	= array( 
						'Comment author must fill out name and email' => 
							'(' . 'Required for anti-spam' . ')', 
						'Enter the address here if you <a href="%s">want your site home page to be different from your WordPress installation directory</a>.' => 
							'<strong>' . 'Not recommended.' . '</strong>' . ' ' . 'This can lead to unexpected behavior.' . ' ' . '<br />' . 'For most websites, these should match.', 
					);
	$dom_wl		= array( 'wp-spamshield', );
	$pl_keys	= array( "wp[\-\ ]*spamshield", "rs[\-\ ]*feedburner", "rs[\-\ ]*head[\-\ ]*cleaner", "rs[\-\ ]*system[\-\ ]*diagnostic", "scrapebreaker", );
	$pl_rgx		= "~(" . ( implode( '|', $pl_keys ) ) . ")~i";
	/* Skip Whitelisted Text Domains */
	if( in_array( $domain, $dom_wl, TRUE ) ) { return $translation; }
	/* Search & Replace */
	foreach( $rep_keys as $s => $r ) {
		if( $text === $r ) { continue; }
		if( $text === $s && $translation === $s ) { return $r; }
	}
	/* Search & Prepend */
	foreach( $pre_keys as $s => $p ) {
		if( $text === $p ) { continue; }
		if( $text === $s && $translation === $s ) { return $p.' '.$s; }
	}
	/* Search & Append */
	foreach( $app_keys as $s => $a ) {
		if( $text === $a ) { continue; }
		if( $text === $s && $translation === $s ) { return $s.' '.$a; }
	}
	/* Text String Keys */
	foreach( $txt_keys as $i => $k ) {
		if( FALSE !== stripos( $translation, $k ) || FALSE !== stripos( $text, $k ) ) { return ''; }
	}
	/* Text Domain Keys */
	foreach( $dom_keys as $i => $k ) {
		if( FALSE !== stripos( $domain, $k ) ) {
			if( preg_match( $pl_rgx, $translation ) || preg_match( $pl_rgx, $text ) ) { return ''; }
		}
	}
	return $translation;
}

/**
 *	Filter debug data.
 *	@dependencies	...
 *	@used by		...
 *	@since			1.9.41
 *	@param			array	$data	Debug data.
 */
function wpss_mu_filter_debug_data( $data ) {
	$db_keys = array( 'mu-plugins', 'dropins', );
	foreach( $db_keys as $k ) { $db_k = 'wp-'.$k; unset( $data[$db_k] ); }
	unset( $data['wp-mu-plugins'] );
	return $data;
}
add_filter( 'debug_information', 'wpss_mu_filter_debug_data', 100000 );

/**
 *	Filters plugin action links
 *	@dependencies	...
 *	@used by		...
 *	@since			1.9.35
 */
function wpss_mu_action_links( $actions, $file, $plugin_data, $status ) {
	if( wpss_mu_dmc() ) {
		$wl_keys = array( 'deactivate', 'delete' ); $wl_actions = $actions;
		foreach( $actions as $k => $v ) { if( !in_array( $k, $wl_keys, TRUE ) ) { unset( $wl_actions[$k] ); } }
		$wl_actions['piracy']	= '<a href="https://www.redsandmarketing.com/plugins/wp-spamshield-anti-spam/#wordpress_security_note" title="Software Piracy Warning" style="font-weight:bold;color:#FF0000;" ping="https://www.redsandmarketing.com/api/v2/ping/wpss/d1/">' . __( 'Software Piracy Warning', 'wp-spamshield' ) . '</a>';
		$wl_actions['purchase'] = '<a href="https://www.redsandmarketing.com/go/cc/wp-spamshield/" title="Buy the Plugin" style="font-weight:bold;color:#FF0000;" ping="https://www.redsandmarketing.com/api/v2/ping/wpss/d2/">' . __( 'Buy the Plugin', 'wp-spamshield' ) . '</a>';
		$actions = $wl_actions;
	}; return $actions;
}

/**
 *	SECURITY - Checks admin notices.
 */
function wpss_mu_admin_notices() {
	$po = 'Plugin' . 'Organizer'; 
	$rem_notices = array( array( 'h' => 'admin_notices', 'cb' => array( $po, 'add_ajax_notices' ), 'p' => 10 ), array( 'h' => 'admin_notices', 'cb' => array( $po, 'compatibility_notices' ), 'p' => 1 ), array( 'h' => 'admin_notices', 'cb' => array( $po, 'display_admin_debug' ), 'p' => 10 ), );
	foreach( $rem_notices as $i => $a ) {
		remove_action( $a['h'], $a['cb'], $a['p'] );
	}
}

/**
 *	Returns 1.
 *	Useful for returning 1 to filters easily. Like `__return_zero()`, `__return_true()`, `__return_false()`, etc.
 *	@dependencies	...
 *	@used by		...
 *	@since			1.9.35
 */
if( !function_exists( '__return_one' ) ) {
	function __return_one() {
		return 1;
	}
}

