<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

trait WPMR_Firewall {

	function firewall_section_ui() {
		?>
		<?php
		$attacks = $this->get_setting( 'attacks' );
		if ( ! empty( $attacks ) ) {
			echo '<p style="display:table;padding:.618em 1em;background:#080;color:white;">Malcure has blocked ' . esc_html( $attacks ) . ' attacks on your website till date! <a style="font-weight:bolder;color:white" target="_blank" href="https://wordpress.org/support/plugin/wp-malware-removal/reviews/#new-post" title="Rate Malcure Malware Scanner &amp; Security Hardening">Rate the plugin</a>&nbsp;★★★★★</strong></p>';
		}
	}

	function fw_block_path_traversal_ui() {
		$value = $this->get_fw_setting( 'fw_block_path_traversal' );
		?>
		<label><input type="checkbox" value="yes" <?php checked( 'yes', $value ); ?> name="wpmr_fw_settings[fw_block_path_traversal]" />Block Path Traversal Attack</label>
		<?php
	}

	function fw_disable_php_upload_ui() {
		$value = $this->get_fw_setting( 'fw_disable_php_upload' );
		?>
		<label><input type="checkbox" value="yes" <?php checked( 'yes', $value ); ?> name="wpmr_fw_settings[fw_disable_php_upload]" />Block attack via PHP file upload</label>
		<?php
	}

	function fw_disable_restapi_user_listing_ui() {
		$value = $this->get_fw_setting( 'fw_disable_restapi_user_listing' );
		?>
		<label><input type="checkbox" value="yes" <?php checked( 'yes', $value ); ?> name="wpmr_fw_settings[fw_disable_restapi_user_listing]" />Block listing of users via API</label>
		<?php
	}

	function fw_disable_user_enumeration_ui() {
		$value = $this->get_fw_setting( 'fw_disable_user_enumeration' );
		?>
		<label><input type="checkbox" value="yes" <?php checked( 'yes', $value ); ?> name="wpmr_fw_settings[fw_disable_user_enumeration]" />Block enumeration of users by web-scrapers / bots</label>
		<?php
	}

	function get_config_search() {
		return '`\/\/\sBEGIN\sWPMR_WAF.*\/\/\sEND WPMR_WAF\s?+`s';
	}

	function patch_wp_config() {
		$file            = WPMR_PLUGIN_DIR . 'inc/waf.php';
		$config_contents = "<?php\n// BEGIN WPMR_WAF. Security Firewall Installed by https://wordpress.org/plugins/wp-malware-removal/\nif( file_exists( '$file' ) ) {\n\t@include_once '$file';\n}\n// END WPMR_WAF";
		$config_search   = $this->get_config_search();
		$wp_config_path  = $this->get_wp_config_path();
		if ( $wp_config_path ) {
			$wp_config   = file_get_contents( $wp_config_path );
			$waf_enabled = preg_match( $config_search, $wp_config );
			if ( ! $waf_enabled ) {
				$wp_config = preg_replace( '`<\?php`s', $config_contents, $wp_config, 1 );
				if ( @copy( $wp_config_path, trailingslashit( dirname( $wp_config_path ) ) . 'wp-config.bak.php' ) ) { // backup in case something goes wrong
					return file_put_contents( $wp_config_path, $wp_config, LOCK_EX );
				} else {
					return new WP_Error( 'broke', 'Can\'t make backup. Aborting!' );
				}
			}
		}
	}

	function unpatch_wp_config() {
		$wp_config_path = $this->get_wp_config_path();
		if ( $wp_config_path ) {
			$wp_config     = file_get_contents( $wp_config_path );
			$config_search = $this->get_config_search();
			$waf_enabled   = preg_match( $config_search, $wp_config );
			if ( $waf_enabled ) {
				$wp_config = preg_replace( $config_search, '', $wp_config );
				return file_put_contents( $wp_config_path, $wp_config, LOCK_EX );
			}
		}
	}

	function waf() {
		if ( ! function_exists( 'get_option' ) ) { // too soon to know what settings the user wants?
			return;
		}
		if ( function_exists( 'wp_get_current_user' ) && is_user_logged_in() ) {
			return;
		}
		if ( function_exists( 'is_admin' ) && is_admin() ) { // exclude wp-admin
			return;
		}
		if ( 'no' != $this->get_fw_setting( 'fw_block_path_traversal' ) ) {
			if ( $request = $this->build_request() ) {
				$re = '/=[\s\/\.]*(\.\.|etc)\//';
				if ( preg_match( $re, $request ) ) {
					$this->update_setting( 'attacks', $this->get_setting( 'attacks' ) + 1 );
					// header( 'location: ' . WPMR_SERVER . '?wpmr_attack_info=' . $this->encode( $this->attack_info() ) . '&wpmr_attack_type=path_traversal&time=' . microtime( true ) );
					die();
				}
			}
		}
		if ( 'no' != $this->get_fw_setting( 'fw_disable_php_upload' ) ) {
			if ( $files = $this->build_files() ) {
				$re = '/name=[^\&]*\.php\&/';
				if ( preg_match( $re, $files ) ) {
					$this->update_setting( 'attacks', $this->get_setting( 'attacks' ) + 1 );
					$ref = ! empty( $_SERVER['HTTP_REFERER'] ) ? sanitize_url( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- HTTP_REFERER sanitized as URL
					// header( 'location: ' . WPMR_SERVER . '?wpmr_attack_info=' . $this->encode( $this->attack_info() ) . '&wpmr_attack_type=php_upload&time=' . microtime( true ) );
					die();
				}
			}
		}
		if ( 'no' != $this->get_fw_setting( 'fw_disable_restapi_user_listing' ) ) {
			if ( $server = $this->build_server() ) {
				$re = '/wp-json\/wp\/v2\/users(?!\/me)/i';
				if ( preg_match( $re, $server ) ) {
					$this->update_setting( 'attacks', $this->get_setting( 'attacks' ) + 1 );
					$ref = ! empty( $_SERVER['HTTP_REFERER'] ) ? sanitize_url( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- HTTP_REFERER sanitized as URL
					// header( 'location: ' . WPMR_SERVER . '?wpmr_attack_info=' . $this->encode( $this->attack_info() ) . '&wpmr_attack_type=restapi_user_listing&time=' . microtime( true ) );
					die();
				}
			}
		}
		if ( 'no' != $this->get_fw_setting( 'fw_disable_user_enumeration' ) ) {
			if ( ( $request = $this->build_request() ) && ( $server = $this->build_server() ) ) {
				$re_srv = '/\&REQUEST_URI=(?!\/wp-admin\/)/i';
				$re_req = '/\&author=[0-9]+\&/';
				if ( preg_match( $re_req, $request ) && preg_match( $re_srv, $server ) ) {
					$this->update_setting( 'attacks', $this->get_setting( 'attacks' ) + 1 );
					// header( 'location: ' . WPMR_SERVER . '?wpmr_attack_info=' . $this->encode( $this->attack_info() ) . '&wpmr_attack_type=user_enumeration&time=' . microtime( true ) );
					die();
				}
			}
		}
	}

	function attack_info() {
		$info = '';
		foreach ( array( 'REMOTE_ADDR', 'HTTP_HOST', 'REQUEST_URI', 'HTTP_REFERER', 'HTTP_USER_AGENT' ) as $var ) {
			$info .= ( isset( $_SERVER[ $var ] ) ? "&wpmr_SERVER_$var=" . urlencode( sanitize_text_field( wp_unslash( $_SERVER[ $var ] ) ) ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Server data sanitized before URL encoding
		}
		return $info . '&wpmr_site_url=' . get_site_url();
	}
}