D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
home
/
everqlsh
/
public_html
/
wp-admin
/
user
/
577040
/
Filename :
waf.zip
back
Copy
PK m�}\zڙ�* �* pomo/translations.phpnu �[��� <?php /** * This is a modified version of the POMO library included with WordPress. The WordPress copyright has been included * for attribution. */ /* WordPress - Web publishing software Copyright 2011-2020 by the contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA This program incorporates work covered by the following copyright and permission notices: b2 is (c) 2001, 2002 Michel Valdrighi - https://cafelog.com Wherever third party code has been used, credit has been given in the code's comments. b2 is released under the GPL and WordPress - Web publishing software Copyright 2003-2010 by the contributors WordPress is released under the GPL */ /** * Class for a set of entries for translation and their associated headers * * @version $Id: translations.php 1157 2015-11-20 04:30:11Z dd32 $ * @package pomo * @subpackage translations */ require_once __DIR__ . '/plural-forms.php'; require_once __DIR__ . '/entry.php'; if ( ! class_exists( 'wfTranslations', false ) ) : class wfTranslations { var $entries = array(); var $headers = array(); /** * Add entry to the PO structure * * @param array|wfTranslation_Entry $entry * @return bool true on success, false if the entry doesn't have a key */ function add_entry( $entry ) { if ( is_array( $entry ) ) { $entry = new wfTranslation_Entry( $entry ); } $key = $entry->key(); if ( false === $key ) { return false; } $this->entries[ $key ] = &$entry; return true; } /** * @param array|wfTranslation_Entry $entry * @return bool */ function add_entry_or_merge( $entry ) { if ( is_array( $entry ) ) { $entry = new wfTranslation_Entry( $entry ); } $key = $entry->key(); if ( false === $key ) { return false; } if ( isset( $this->entries[ $key ] ) ) { $this->entries[ $key ]->merge_with( $entry ); } else { $this->entries[ $key ] = &$entry; } return true; } /** * Sets $header PO header to $value * * If the header already exists, it will be overwritten * * TODO: this should be out of this class, it is gettext specific * * @param string $header header name, without trailing : * @param string $value header value, without trailing \n */ function set_header( $header, $value ) { $this->headers[ $header ] = $value; } /** * @param array $headers */ function set_headers( $headers ) { foreach ( $headers as $header => $value ) { $this->set_header( $header, $value ); } } /** * @param string $header */ function get_header( $header ) { return isset( $this->headers[ $header ] ) ? $this->headers[ $header ] : false; } /** * @param wfTranslation_Entry $entry */ function translate_entry( &$entry ) { $key = $entry->key(); return isset( $this->entries[ $key ] ) ? $this->entries[ $key ] : false; } /** * @param string $singular * @param string $context * @return string */ function translate( $singular, $context = null ) { $entry = new wfTranslation_Entry( array( 'singular' => $singular, 'context' => $context, ) ); $translated = $this->translate_entry( $entry ); return ( $translated && ! empty( $translated->translations ) ) ? $translated->translations[0] : $singular; } /** * Given the number of items, returns the 0-based index of the plural form to use * * Here, in the base Translations class, the common logic for English is implemented: * 0 if there is one element, 1 otherwise * * This function should be overridden by the subclasses. For example MO/PO can derive the logic * from their headers. * * @param integer $count number of items */ function select_plural_form( $count ) { return 1 == $count ? 0 : 1; } /** * @return int */ function get_plural_forms_count() { return 2; } /** * @param string $singular * @param string $plural * @param int $count * @param string $context */ function translate_plural( $singular, $plural, $count, $context = null ) { $entry = new wfTranslation_Entry( array( 'singular' => $singular, 'plural' => $plural, 'context' => $context, ) ); $translated = $this->translate_entry( $entry ); $index = $this->select_plural_form( $count ); $total_plural_forms = $this->get_plural_forms_count(); if ( $translated && 0 <= $index && $index < $total_plural_forms && is_array( $translated->translations ) && isset( $translated->translations[ $index ] ) ) { return $translated->translations[ $index ]; } else { return 1 == $count ? $singular : $plural; } } /** * Merge $other in the current object. * * @param Object $other Another Translation object, whose translations will be merged in this one (passed by reference). * @return void */ function merge_with( &$other ) { foreach ( $other->entries as $entry ) { $this->entries[ $entry->key() ] = $entry; } } /** * @param object $other */ function merge_originals_with( &$other ) { foreach ( $other->entries as $entry ) { if ( ! isset( $this->entries[ $entry->key() ] ) ) { $this->entries[ $entry->key() ] = $entry; } else { $this->entries[ $entry->key() ]->merge_with( $entry ); } } } } class wfGettext_Translations extends wfTranslations { private $_gettext_select_plural_form = null; /** * The gettext implementation of select_plural_form. * * It lives in this class, because there are more than one descendand, which will use it and * they can't share it effectively. * * @param int $count */ function gettext_select_plural_form( $count ) { if ( ! isset( $this->_gettext_select_plural_form ) || is_null( $this->_gettext_select_plural_form ) ) { list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) ); $this->_nplurals = $nplurals; $this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression ); } return call_user_func( $this->_gettext_select_plural_form, $count ); } /** * @param string $header * @return array */ function nplurals_and_expression_from_header( $header ) { if ( preg_match( '/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches ) ) { $nplurals = (int) $matches[1]; $expression = trim( $matches[2] ); return array( $nplurals, $expression ); } else { return array( 2, 'n != 1' ); } } /** * Makes a function, which will return the right translation index, according to the * plural forms header * * @param int $nplurals * @param string $expression */ function make_plural_form_function( $nplurals, $expression ) { try { $handler = new wfPlural_Forms( rtrim( $expression, ';' ) ); return array( $handler, 'get' ); } catch ( Exception $e ) { // Fall back to default plural-form function. return $this->make_plural_form_function( 2, 'n != 1' ); } } /** * Adds parentheses to the inner parts of ternary operators in * plural expressions, because PHP evaluates ternary oerators from left to right * * @param string $expression the expression without parentheses * @return string the expression with parentheses added */ function parenthesize_plural_exression( $expression ) { $expression .= ';'; $res = ''; $depth = 0; for ( $i = 0; $i < strlen( $expression ); ++$i ) { $char = $expression[ $i ]; switch ( $char ) { case '?': $res .= ' ? ('; $depth++; break; case ':': $res .= ') : ('; break; case ';': $res .= str_repeat( ')', $depth ) . ';'; $depth = 0; break; default: $res .= $char; } } return rtrim( $res, ';' ); } /** * @param string $translation * @return array */ function make_headers( $translation ) { $headers = array(); // Sometimes \n's are used instead of real new lines. $translation = str_replace( '\n', "\n", $translation ); $lines = explode( "\n", $translation ); foreach ( $lines as $line ) { $parts = explode( ':', $line, 2 ); if ( ! isset( $parts[1] ) ) { continue; } $headers[ trim( $parts[0] ) ] = trim( $parts[1] ); } return $headers; } /** * @param string $header * @param string $value */ function set_header( $header, $value ) { parent::set_header( $header, $value ); if ( 'Plural-Forms' === $header ) { list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header( $this->get_header( 'Plural-Forms' ) ); $this->_nplurals = $nplurals; $this->_gettext_select_plural_form = $this->make_plural_form_function( $nplurals, $expression ); } } } endif; if ( ! class_exists( 'wfNOOP_Translations', false ) ) : /** * Provides the same interface as Translations, but doesn't do anything */ class wfNOOP_Translations { var $entries = array(); var $headers = array(); function add_entry( $entry ) { return true; } /** * @param string $header * @param string $value */ function set_header( $header, $value ) { } /** * @param array $headers */ function set_headers( $headers ) { } /** * @param string $header * @return false */ function get_header( $header ) { return false; } /** * @param wfTranslation_Entry $entry * @return false */ function translate_entry( &$entry ) { return false; } /** * @param string $singular * @param string $context */ function translate( $singular, $context = null ) { return $singular; } /** * @param int $count * @return bool */ function select_plural_form( $count ) { return 1 == $count ? 0 : 1; } /** * @return int */ function get_plural_forms_count() { return 2; } /** * @param string $singular * @param string $plural * @param int $count * @param string $context */ function translate_plural( $singular, $plural, $count, $context = null ) { return 1 == $count ? $singular : $plural; } /** * @param object $other */ function merge_with( &$other ) { } } endif;PK n�}\l�r��) �) pomo/mo.phpnu �[��� <?php /** * This is a modified version of the POMO library included with WordPress. The WordPress copyright has been included * for attribution. */ /* WordPress - Web publishing software Copyright 2011-2020 by the contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA This program incorporates work covered by the following copyright and permission notices: b2 is (c) 2001, 2002 Michel Valdrighi - https://cafelog.com Wherever third party code has been used, credit has been given in the code's comments. b2 is released under the GPL and WordPress - Web publishing software Copyright 2003-2010 by the contributors WordPress is released under the GPL */ /** * Class for working with MO files * * @version $Id: mo.php 1157 2015-11-20 04:30:11Z dd32 $ * @package pomo * @subpackage mo */ require_once __DIR__ . '/translations.php'; require_once __DIR__ . '/streams.php'; if ( ! class_exists( 'wfMO', false ) ) : class wfMO extends wfGettext_Translations { var $_nplurals = 2; /** * Loaded MO file. * * @var string */ private $filename = ''; /** * Returns the loaded MO file. * * @return string The loaded MO file. */ public function get_filename() { return $this->filename; } /** * Fills up with the entries from MO file $filename * * @param string $filename MO file to load * @return bool True if the import from file was successful, otherwise false. */ function import_from_file( $filename ) { $reader = new wfPOMO_FileReader( $filename ); if ( ! $reader->is_resource() ) { return false; } $this->filename = (string) $filename; return $this->import_from_reader( $reader ); } /** * @param string $filename * @return bool */ function export_to_file( $filename ) { $fh = fopen( $filename, 'wb' ); if ( ! $fh ) { return false; } $res = $this->export_to_file_handle( $fh ); fclose( $fh ); return $res; } /** * @return string|false */ function export() { $tmp_fh = fopen( 'php://temp', 'r+' ); if ( ! $tmp_fh ) { return false; } $this->export_to_file_handle( $tmp_fh ); rewind( $tmp_fh ); return stream_get_contents( $tmp_fh ); } /** * @param wfTranslation_Entry $entry * @return bool */ function is_entry_good_for_export( $entry ) { if ( empty( $entry->translations ) ) { return false; } if ( ! array_filter( $entry->translations ) ) { return false; } return true; } /** * @param resource $fh * @return true */ function export_to_file_handle( $fh ) { $entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) ); ksort( $entries ); $magic = 0x950412de; $revision = 0; $total = count( $entries ) + 1; // All the headers are one entry. $originals_lenghts_addr = 28; $translations_lenghts_addr = $originals_lenghts_addr + 8 * $total; $size_of_hash = 0; $hash_addr = $translations_lenghts_addr + 8 * $total; $current_addr = $hash_addr; fwrite( $fh, pack( 'V*', $magic, $revision, $total, $originals_lenghts_addr, $translations_lenghts_addr, $size_of_hash, $hash_addr ) ); fseek( $fh, $originals_lenghts_addr ); // Headers' msgid is an empty string. fwrite( $fh, pack( 'VV', 0, $current_addr ) ); $current_addr++; $originals_table = "\0"; $reader = new wfPOMO_Reader(); foreach ( $entries as $entry ) { $originals_table .= $this->export_original( $entry ) . "\0"; $length = $reader->strlen( $this->export_original( $entry ) ); fwrite( $fh, pack( 'VV', $length, $current_addr ) ); $current_addr += $length + 1; // Account for the NULL byte after. } $exported_headers = $this->export_headers(); fwrite( $fh, pack( 'VV', $reader->strlen( $exported_headers ), $current_addr ) ); $current_addr += strlen( $exported_headers ) + 1; $translations_table = $exported_headers . "\0"; foreach ( $entries as $entry ) { $translations_table .= $this->export_translations( $entry ) . "\0"; $length = $reader->strlen( $this->export_translations( $entry ) ); fwrite( $fh, pack( 'VV', $length, $current_addr ) ); $current_addr += $length + 1; } fwrite( $fh, $originals_table ); fwrite( $fh, $translations_table ); return true; } /** * @param wfTranslation_Entry $entry * @return string */ function export_original( $entry ) { // TODO: Warnings for control characters. $exported = $entry->singular; if ( $entry->is_plural ) { $exported .= "\0" . $entry->plural; } if ( $entry->context ) { $exported = $entry->context . "\4" . $exported; } return $exported; } /** * @param wfTranslation_Entry $entry * @return string */ function export_translations( $entry ) { // TODO: Warnings for control characters. return $entry->is_plural ? implode( "\0", $entry->translations ) : $entry->translations[0]; } /** * @return string */ function export_headers() { $exported = ''; foreach ( $this->headers as $header => $value ) { $exported .= "$header: $value\n"; } return $exported; } /** * @param int $magic * @return string|false */ function get_byteorder( $magic ) { // The magic is 0x950412de. // bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565 $magic_little = (int) - 1794895138; $magic_little_64 = (int) 2500072158; // 0xde120495 $magic_big = ( (int) - 569244523 ) & 0xFFFFFFFF; if ( $magic_little == $magic || $magic_little_64 == $magic ) { return 'little'; } elseif ( $magic_big == $magic ) { return 'big'; } else { return false; } } /** * @param wfPOMO_FileReader $reader * @return bool True if the import was successful, otherwise false. */ function import_from_reader( $reader ) { $endian_string = wfMO::get_byteorder( $reader->readint32() ); if ( false === $endian_string ) { return false; } $reader->setEndian( $endian_string ); $endian = ( 'big' === $endian_string ) ? 'N' : 'V'; $header = $reader->read( 24 ); if ( $reader->strlen( $header ) != 24 ) { return false; } // Parse header. $header = unpack( "{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header ); if ( ! is_array( $header ) ) { return false; } // Support revision 0 of MO format specs, only. if ( 0 != $header['revision'] ) { return false; } // Seek to data blocks. $reader->seekto( $header['originals_lenghts_addr'] ); // Read originals' indices. $originals_lengths_length = $header['translations_lenghts_addr'] - $header['originals_lenghts_addr']; if ( $originals_lengths_length != $header['total'] * 8 ) { return false; } $originals = $reader->read( $originals_lengths_length ); if ( $reader->strlen( $originals ) != $originals_lengths_length ) { return false; } // Read translations' indices. $translations_lenghts_length = $header['hash_addr'] - $header['translations_lenghts_addr']; if ( $translations_lenghts_length != $header['total'] * 8 ) { return false; } $translations = $reader->read( $translations_lenghts_length ); if ( $reader->strlen( $translations ) != $translations_lenghts_length ) { return false; } // Transform raw data into set of indices. $originals = $reader->str_split( $originals, 8 ); $translations = $reader->str_split( $translations, 8 ); // Skip hash table. $strings_addr = $header['hash_addr'] + $header['hash_length'] * 4; $reader->seekto( $strings_addr ); $strings = $reader->read_all(); $reader->close(); for ( $i = 0; $i < $header['total']; $i++ ) { $o = unpack( "{$endian}length/{$endian}pos", $originals[ $i ] ); $t = unpack( "{$endian}length/{$endian}pos", $translations[ $i ] ); if ( ! $o || ! $t ) { return false; } // Adjust offset due to reading strings to separate space before. $o['pos'] -= $strings_addr; $t['pos'] -= $strings_addr; $original = $reader->substr( $strings, $o['pos'], $o['length'] ); $translation = $reader->substr( $strings, $t['pos'], $t['length'] ); if ( '' === $original ) { $this->set_headers( $this->make_headers( $translation ) ); } else { $entry = &$this->make_entry( $original, $translation ); $this->entries[ $entry->key() ] = &$entry; } } return true; } /** * Build a Translation_Entry from original string and translation strings, * found in a MO file * * @static * @param string $original original string to translate from MO file. Might contain * 0x04 as context separator or 0x00 as singular/plural separator * @param string $translation translation string from MO file. Might contain * 0x00 as a plural translations separator * @return wfTranslation_Entry Entry instance. */ function &make_entry( $original, $translation ) { $entry = new wfTranslation_Entry(); // Look for context, separated by \4. $parts = explode( "\4", $original ); if ( isset( $parts[1] ) ) { $original = $parts[1]; $entry->context = $parts[0]; } // Look for plural original. $parts = explode( "\0", $original ); $entry->singular = $parts[0]; if ( isset( $parts[1] ) ) { $entry->is_plural = true; $entry->plural = $parts[1]; } // Plural translations are also separated by \0. $entry->translations = explode( "\0", $translation ); return $entry; } /** * @param int $count * @return string */ function select_plural_form( $count ) { return $this->gettext_select_plural_form( $count ); } /** * @return int */ function get_plural_forms_count() { return $this->_nplurals; } } endif; PK p�}\���9� � pomo/entry.phpnu �[��� <?php /** * This is a modified version of the POMO library included with WordPress. The WordPress copyright has been included * for attribution. */ /* WordPress - Web publishing software Copyright 2011-2020 by the contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA This program incorporates work covered by the following copyright and permission notices: b2 is (c) 2001, 2002 Michel Valdrighi - https://cafelog.com Wherever third party code has been used, credit has been given in the code's comments. b2 is released under the GPL and WordPress - Web publishing software Copyright 2003-2010 by the contributors WordPress is released under the GPL */ /** * Contains Translation_Entry class * * @version $Id: entry.php 1157 2015-11-20 04:30:11Z dd32 $ * @package pomo * @subpackage entry */ if ( ! class_exists( 'wfTranslation_Entry', false ) ) : /** * Translation_Entry class encapsulates a translatable string */ class wfTranslation_Entry { /** * Whether the entry contains a string and its plural form, default is false * * @var boolean */ var $is_plural = false; var $context = null; var $singular = null; var $plural = null; var $translations = array(); var $translator_comments = ''; var $extracted_comments = ''; var $references = array(); var $flags = array(); /** * @param array $args associative array, support following keys: * - singular (string) -- the string to translate, if omitted and empty entry will be created * - plural (string) -- the plural form of the string, setting this will set {@link $is_plural} to true * - translations (array) -- translations of the string and possibly -- its plural forms * - context (string) -- a string differentiating two equal strings used in different contexts * - translator_comments (string) -- comments left by translators * - extracted_comments (string) -- comments left by developers * - references (array) -- places in the code this strings is used, in relative_to_root_path/file.php:linenum form * - flags (array) -- flags like php-format */ function __construct( $args = array() ) { // If no singular -- empty object. if ( ! isset( $args['singular'] ) ) { return; } // Get member variable values from args hash. foreach ( $args as $varname => $value ) { $this->$varname = $value; } if ( isset( $args['plural'] ) && $args['plural'] ) { $this->is_plural = true; } if ( ! is_array( $this->translations ) ) { $this->translations = array(); } if ( ! is_array( $this->references ) ) { $this->references = array(); } if ( ! is_array( $this->flags ) ) { $this->flags = array(); } } /** * Generates a unique key for this entry * * @return string|bool the key or false if the entry is empty */ function key() { if ( null === $this->singular || '' === $this->singular ) { return false; } // Prepend context and EOT, like in MO files. $key = ! $this->context ? $this->singular : $this->context . "\4" . $this->singular; // Standardize on \n line endings. $key = str_replace( array( "\r\n", "\r" ), "\n", $key ); return $key; } /** * @param object $other */ function merge_with( &$other ) { $this->flags = array_unique( array_merge( $this->flags, $other->flags ) ); $this->references = array_unique( array_merge( $this->references, $other->references ) ); if ( $this->extracted_comments != $other->extracted_comments ) { $this->extracted_comments .= $other->extracted_comments; } } } endif; PK q�}\�3� � pomo/plural-forms.phpnu �[��� <?php /** * This is a modified version of the POMO library included with WordPress. The WordPress copyright has been included * for attribution. */ /* WordPress - Web publishing software Copyright 2011-2020 by the contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA This program incorporates work covered by the following copyright and permission notices: b2 is (c) 2001, 2002 Michel Valdrighi - https://cafelog.com Wherever third party code has been used, credit has been given in the code's comments. b2 is released under the GPL and WordPress - Web publishing software Copyright 2003-2010 by the contributors WordPress is released under the GPL */ /** * A gettext Plural-Forms parser. * * @since 4.9.0 */ class wfPlural_Forms { /** * Operator characters. * * @since 4.9.0 * @var string OP_CHARS Operator characters. */ const OP_CHARS = '|&><!=%?:'; /** * Valid number characters. * * @since 4.9.0 * @var string NUM_CHARS Valid number characters. */ const NUM_CHARS = '0123456789'; /** * Operator precedence. * * Operator precedence from highest to lowest. Higher numbers indicate * higher precedence, and are executed first. * * @see https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#Operator_precedence * * @since 4.9.0 * @var array $op_precedence Operator precedence from highest to lowest. */ protected static $op_precedence = array( '%' => 6, '<' => 5, '<=' => 5, '>' => 5, '>=' => 5, '==' => 4, '!=' => 4, '&&' => 3, '||' => 2, '?:' => 1, '?' => 1, '(' => 0, ')' => 0, ); /** * Tokens generated from the string. * * @since 4.9.0 * @var array $tokens List of tokens. */ protected $tokens = array(); /** * Cache for repeated calls to the function. * * @since 4.9.0 * @var array $cache Map of $n => $result */ protected $cache = array(); /** * Constructor. * * @since 4.9.0 * * @param string $str Plural function (just the bit after `plural=` from Plural-Forms) */ public function __construct( $str ) { $this->parse( $str ); } /** * Parse a Plural-Forms string into tokens. * * Uses the shunting-yard algorithm to convert the string to Reverse Polish * Notation tokens. * * @since 4.9.0 * * @param string $str String to parse. */ protected function parse( $str ) { $pos = 0; $len = strlen( $str ); // Convert infix operators to postfix using the shunting-yard algorithm. $output = array(); $stack = array(); while ( $pos < $len ) { $next = substr( $str, $pos, 1 ); switch ( $next ) { // Ignore whitespace. case ' ': case "\t": $pos++; break; // Variable (n). case 'n': $output[] = array( 'var' ); $pos++; break; // Parentheses. case '(': $stack[] = $next; $pos++; break; case ')': $found = false; while ( ! empty( $stack ) ) { $o2 = $stack[ count( $stack ) - 1 ]; if ( '(' !== $o2 ) { $output[] = array( 'op', array_pop( $stack ) ); continue; } // Discard open paren. array_pop( $stack ); $found = true; break; } if ( ! $found ) { throw new Exception( 'Mismatched parentheses' ); } $pos++; break; // Operators. case '|': case '&': case '>': case '<': case '!': case '=': case '%': case '?': $end_operator = strspn( $str, self::OP_CHARS, $pos ); $operator = substr( $str, $pos, $end_operator ); if ( ! array_key_exists( $operator, self::$op_precedence ) ) { throw new Exception( sprintf( 'Unknown operator "%s"', $operator ) ); } while ( ! empty( $stack ) ) { $o2 = $stack[ count( $stack ) - 1 ]; // Ternary is right-associative in C. if ( '?:' === $operator || '?' === $operator ) { if ( self::$op_precedence[ $operator ] >= self::$op_precedence[ $o2 ] ) { break; } } elseif ( self::$op_precedence[ $operator ] > self::$op_precedence[ $o2 ] ) { break; } $output[] = array( 'op', array_pop( $stack ) ); } $stack[] = $operator; $pos += $end_operator; break; // Ternary "else". case ':': $found = false; $s_pos = count( $stack ) - 1; while ( $s_pos >= 0 ) { $o2 = $stack[ $s_pos ]; if ( '?' !== $o2 ) { $output[] = array( 'op', array_pop( $stack ) ); $s_pos--; continue; } // Replace. $stack[ $s_pos ] = '?:'; $found = true; break; } if ( ! $found ) { throw new Exception( 'Missing starting "?" ternary operator' ); } $pos++; break; // Default - number or invalid. default: if ( $next >= '0' && $next <= '9' ) { $span = strspn( $str, self::NUM_CHARS, $pos ); $output[] = array( 'value', intval( substr( $str, $pos, $span ) ) ); $pos += $span; break; } throw new Exception( sprintf( 'Unknown symbol "%s"', $next ) ); } } while ( ! empty( $stack ) ) { $o2 = array_pop( $stack ); if ( '(' === $o2 || ')' === $o2 ) { throw new Exception( 'Mismatched parentheses' ); } $output[] = array( 'op', $o2 ); } $this->tokens = $output; } /** * Get the plural form for a number. * * Caches the value for repeated calls. * * @since 4.9.0 * * @param int $num Number to get plural form for. * @return int Plural form value. */ public function get( $num ) { if ( isset( $this->cache[ $num ] ) ) { return $this->cache[ $num ]; } $this->cache[ $num ] = $this->execute( $num ); return $this->cache[ $num ]; } /** * Execute the plural form function. * * @since 4.9.0 * * @param int $n Variable "n" to substitute. * @return int Plural form value. */ public function execute( $n ) { $stack = array(); $i = 0; $total = count( $this->tokens ); while ( $i < $total ) { $next = $this->tokens[ $i ]; $i++; if ( 'var' === $next[0] ) { $stack[] = $n; continue; } elseif ( 'value' === $next[0] ) { $stack[] = $next[1]; continue; } // Only operators left. switch ( $next[1] ) { case '%': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 % $v2; break; case '||': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 || $v2; break; case '&&': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 && $v2; break; case '<': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 < $v2; break; case '<=': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 <= $v2; break; case '>': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 > $v2; break; case '>=': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 >= $v2; break; case '!=': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 != $v2; break; case '==': $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 == $v2; break; case '?:': $v3 = array_pop( $stack ); $v2 = array_pop( $stack ); $v1 = array_pop( $stack ); $stack[] = $v1 ? $v2 : $v3; break; default: throw new Exception( sprintf( 'Unknown operator "%s"', $next[1] ) ); } } if ( count( $stack ) !== 1 ) { throw new Exception( 'Too many values remaining on the stack' ); } return (int) $stack[0]; } } PK r�}\��O�H H pomo/streams.phpnu �[��� <?php /** * This is a modified version of the POMO library included with WordPress. The WordPress copyright has been included * for attribution. */ /* WordPress - Web publishing software Copyright 2011-2020 by the contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA This program incorporates work covered by the following copyright and permission notices: b2 is (c) 2001, 2002 Michel Valdrighi - https://cafelog.com Wherever third party code has been used, credit has been given in the code's comments. b2 is released under the GPL and WordPress - Web publishing software Copyright 2003-2010 by the contributors WordPress is released under the GPL */ /** * Classes, which help reading streams of data from files. * Based on the classes from Danilo Segan <danilo@kvota.net> * * @version $Id: streams.php 1157 2015-11-20 04:30:11Z dd32 $ * @package pomo * @subpackage streams */ if ( ! class_exists( 'wfPOMO_Reader', false ) ) : class wfPOMO_Reader { var $endian = 'little'; var $_post = ''; private $is_overloaded; protected $_pos; /** * PHP5 constructor. */ function __construct() { $this->is_overloaded = ( ( ini_get( 'mbstring.func_overload' ) & 2 ) != 0 ) && function_exists( 'mb_substr' ); // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated $this->_pos = 0; } /** * Sets the endianness of the file. * * @param string $endian Set the endianness of the file. Accepts 'big', or 'little'. */ function setEndian( $endian ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid $this->endian = $endian; } /** * Reads a 32bit Integer from the Stream * * @return mixed The integer, corresponding to the next 32 bits from * the stream of false if there are not enough bytes or on error */ function readint32() { $bytes = $this->read( 4 ); if ( 4 != $this->strlen( $bytes ) ) { return false; } $endian_letter = ( 'big' === $this->endian ) ? 'N' : 'V'; $int = unpack( $endian_letter, $bytes ); return reset( $int ); } /** * Reads an array of 32-bit Integers from the Stream * * @param integer $count How many elements should be read * @return mixed Array of integers or false if there isn't * enough data or on error */ function readint32array( $count ) { $bytes = $this->read( 4 * $count ); if ( 4 * $count != $this->strlen( $bytes ) ) { return false; } $endian_letter = ( 'big' === $this->endian ) ? 'N' : 'V'; return unpack( $endian_letter . $count, $bytes ); } /** * @param string $string * @param int $start * @param int $length * @return string */ function substr( $string, $start, $length ) { if ( $this->is_overloaded ) { return mb_substr( $string, $start, $length, 'ascii' ); } else { return substr( $string, $start, $length ); } } /** * @param string $string * @return int */ function strlen( $string ) { if ( $this->is_overloaded ) { return mb_strlen( $string, 'ascii' ); } else { return strlen( $string ); } } /** * @param string $string * @param int $chunk_size * @return array */ function str_split( $string, $chunk_size ) { if ( ! function_exists( 'str_split' ) ) { $length = $this->strlen( $string ); $out = array(); for ( $i = 0; $i < $length; $i += $chunk_size ) { $out[] = $this->substr( $string, $i, $chunk_size ); } return $out; } else { return str_split( $string, $chunk_size ); } } /** * @return int */ function pos() { return $this->_pos; } /** * @return true */ function is_resource() { return true; } /** * @return true */ function close() { return true; } } endif; if ( ! class_exists( 'wfPOMO_FileReader', false ) ) : class wfPOMO_FileReader extends wfPOMO_Reader { private $_f; /** * @param string $filename */ function __construct( $filename ) { parent::__construct(); $this->_f = fopen( $filename, 'rb' ); } /** * @param int $bytes * @return string|false Returns read string, otherwise false. */ function read( $bytes ) { return fread( $this->_f, $bytes ); } /** * @param int $pos * @return boolean */ function seekto( $pos ) { if ( -1 == fseek( $this->_f, $pos, SEEK_SET ) ) { return false; } $this->_pos = $pos; return true; } /** * @return bool */ function is_resource() { return is_resource( $this->_f ); } /** * @return bool */ function feof() { return feof( $this->_f ); } /** * @return bool */ function close() { return fclose( $this->_f ); } /** * @return string */ function read_all() { $all = ''; while ( ! $this->feof() ) { $all .= $this->read( 4096 ); } return $all; } } endif; if ( ! class_exists( 'wfPOMO_StringReader', false ) ) : /** * Provides file-like methods for manipulating a string instead * of a physical file. */ class wfPOMO_StringReader extends wfPOMO_Reader { var $_str = ''; /** * PHP5 constructor. */ function __construct( $str = '' ) { parent::__construct(); $this->_str = $str; $this->_pos = 0; } /** * @param string $bytes * @return string */ function read( $bytes ) { $data = $this->substr( $this->_str, $this->_pos, $bytes ); $this->_pos += $bytes; if ( $this->strlen( $this->_str ) < $this->_pos ) { $this->_pos = $this->strlen( $this->_str ); } return $data; } /** * @param int $pos * @return int */ function seekto( $pos ) { $this->_pos = $pos; if ( $this->strlen( $this->_str ) < $this->_pos ) { $this->_pos = $this->strlen( $this->_str ); } return $this->_pos; } /** * @return int */ function length() { return $this->strlen( $this->_str ); } /** * @return string */ function read_all() { return $this->substr( $this->_str, $this->_pos, $this->strlen( $this->_str ) ); } } endif; if ( ! class_exists( 'wfPOMO_CachedFileReader', false ) ) : /** * Reads the contents of the file in the beginning. */ class wfPOMO_CachedFileReader extends wfPOMO_StringReader { /** * PHP5 constructor. */ function __construct( $filename ) { parent::__construct(); $this->_str = file_get_contents( $filename ); if ( false === $this->_str ) { return false; } $this->_pos = 0; } } endif; if ( ! class_exists( 'wfPOMO_CachedIntFileReader', false ) ) : /** * Reads the contents of the file in the beginning. */ class wfPOMO_CachedIntFileReader extends wfPOMO_CachedFileReader { /** * PHP5 constructor. */ public function __construct( $filename ) { parent::__construct( $filename ); } } endif; PK s�}\����"? "? pomo/po.phpnu �[��� <?php /** * This is a modified version of the POMO library included with WordPress. The WordPress copyright has been included * for attribution. */ /* WordPress - Web publishing software Copyright 2011-2020 by the contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA This program incorporates work covered by the following copyright and permission notices: b2 is (c) 2001, 2002 Michel Valdrighi - https://cafelog.com Wherever third party code has been used, credit has been given in the code's comments. b2 is released under the GPL and WordPress - Web publishing software Copyright 2003-2010 by the contributors WordPress is released under the GPL */ /** * Class for working with PO files * * @version $Id: po.php 1158 2015-11-20 04:31:23Z dd32 $ * @package pomo * @subpackage po */ require_once __DIR__ . '/translations.php'; if ( ! defined( 'WF_PO_MAX_LINE_LEN' ) ) { define( 'WF_PO_MAX_LINE_LEN', 79 ); } ini_set( 'auto_detect_line_endings', 1 ); /** * Routines for working with PO files */ if ( ! class_exists( 'wfPO', false ) ) : class wfPO extends wfGettext_Translations { var $comments_before_headers = ''; /** * Exports headers to a PO entry * * @return string msgid/msgstr PO entry for this PO file headers, doesn't contain newline at the end */ function export_headers() { $header_string = ''; foreach ( $this->headers as $header => $value ) { $header_string .= "$header: $value\n"; } $poified = wfPO::poify( $header_string ); if ( $this->comments_before_headers ) { $before_headers = $this->prepend_each_line( rtrim( $this->comments_before_headers ) . "\n", '# ' ); } else { $before_headers = ''; } return rtrim( "{$before_headers}msgid \"\"\nmsgstr $poified" ); } /** * Exports all entries to PO format * * @return string sequence of mgsgid/msgstr PO strings, doesn't containt newline at the end */ function export_entries() { // TODO: Sorting. return implode( "\n\n", array_map( array('wfPO', 'export_entry' ), $this->entries ) ); } /** * Exports the whole PO file as a string * * @param bool $include_headers whether to include the headers in the export * @return string ready for inclusion in PO file string for headers and all the enrtries */ function export( $include_headers = true ) { $res = ''; if ( $include_headers ) { $res .= $this->export_headers(); $res .= "\n\n"; } $res .= $this->export_entries(); return $res; } /** * Same as {@link export}, but writes the result to a file * * @param string $filename Where to write the PO string. * @param bool $include_headers Whether to include the headers in the export. * @return bool true on success, false on error */ function export_to_file( $filename, $include_headers = true ) { $fh = fopen( $filename, 'w' ); if ( false === $fh ) { return false; } $export = $this->export( $include_headers ); $res = fwrite( $fh, $export ); if ( false === $res ) { return false; } return fclose( $fh ); } /** * Text to include as a comment before the start of the PO contents * * Doesn't need to include # in the beginning of lines, these are added automatically * * @param string $text Text to include as a comment. */ function set_comment_before_headers( $text ) { $this->comments_before_headers = $text; } /** * Formats a string in PO-style * * @param string $string the string to format * @return string the poified string */ public static function poify( $string ) { $quote = '"'; $slash = '\\'; $newline = "\n"; $replaces = array( "$slash" => "{$slash}{$slash}", "$quote" => "{$slash}{$quote}", "\t" => '\t', ); $string = str_replace( array_keys( $replaces ), array_values( $replaces ), $string ); $po = $quote . implode( "{$slash}n{$quote}{$newline}{$quote}", explode( $newline, $string ) ) . $quote; // Add empty string on first line for readbility. if ( false !== strpos( $string, $newline ) && ( substr_count( $string, $newline ) > 1 || substr( $string, -strlen( $newline ) ) !== $newline ) ) { $po = "{$quote}{$quote}{$newline}{$po}"; } // Remove empty strings. $po = str_replace( "{$newline}{$quote}{$quote}", '', $po ); return $po; } /** * Gives back the original string from a PO-formatted string * * @param string $string PO-formatted string * @return string enascaped string */ public static function unpoify( $string ) { $escapes = array( 't' => "\t", 'n' => "\n", 'r' => "\r", '\\' => '\\', ); $lines = array_map( 'trim', explode( "\n", $string ) ); $lines = array_map( array('wfPO', 'trim_quotes' ), $lines ); $unpoified = ''; $previous_is_backslash = false; foreach ( $lines as $line ) { preg_match_all( '/./u', $line, $chars ); $chars = $chars[0]; foreach ( $chars as $char ) { if ( ! $previous_is_backslash ) { if ( '\\' === $char ) { $previous_is_backslash = true; } else { $unpoified .= $char; } } else { $previous_is_backslash = false; $unpoified .= isset( $escapes[ $char ] ) ? $escapes[ $char ] : $char; } } } // Standardise the line endings on imported content, technically PO files shouldn't contain \r. $unpoified = str_replace( array( "\r\n", "\r" ), "\n", $unpoified ); return $unpoified; } /** * Inserts $with in the beginning of every new line of $string and * returns the modified string * * @param string $string prepend lines in this string * @param string $with prepend lines with this string */ public static function prepend_each_line( $string, $with ) { $lines = explode( "\n", $string ); $append = ''; if ( "\n" === substr( $string, -1 ) && '' === end( $lines ) ) { /* * Last line might be empty because $string was terminated * with a newline, remove it from the $lines array, * we'll restore state by re-terminating the string at the end. */ array_pop( $lines ); $append = "\n"; } foreach ( $lines as &$line ) { $line = $with . $line; } unset( $line ); return implode( "\n", $lines ) . $append; } /** * Prepare a text as a comment -- wraps the lines and prepends # * and a special character to each line * * @access private * @param string $text the comment text * @param string $char character to denote a special PO comment, * like :, default is a space */ public static function comment_block( $text, $char = ' ' ) { $text = wordwrap( $text, WF_PO_MAX_LINE_LEN - 3 ); return wfPO::prepend_each_line( $text, "#$char " ); } /** * Builds a string from the entry for inclusion in PO file * * @param wfTranslation_Entry $entry the entry to convert to po string (passed by reference). * @return string|false PO-style formatted string for the entry or * false if the entry is empty */ public static function export_entry( &$entry ) { if ( null === $entry->singular || '' === $entry->singular ) { return false; } $po = array(); if ( ! empty( $entry->translator_comments ) ) { $po[] = wfPO::comment_block( $entry->translator_comments ); } if ( ! empty( $entry->extracted_comments ) ) { $po[] = wfPO::comment_block( $entry->extracted_comments, '.' ); } if ( ! empty( $entry->references ) ) { $po[] = wfPO::comment_block( implode( ' ', $entry->references ), ':' ); } if ( ! empty( $entry->flags ) ) { $po[] = wfPO::comment_block( implode( ', ', $entry->flags ), ',' ); } if ( $entry->context ) { $po[] = 'msgctxt ' . wfPO::poify( $entry->context ); } $po[] = 'msgid ' . wfPO::poify( $entry->singular ); if ( ! $entry->is_plural ) { $translation = empty( $entry->translations ) ? '' : $entry->translations[0]; $translation = wfPO::match_begin_and_end_newlines( $translation, $entry->singular ); $po[] = 'msgstr ' . wfPO::poify( $translation ); } else { $po[] = 'msgid_plural ' . wfPO::poify( $entry->plural ); $translations = empty( $entry->translations ) ? array( '', '' ) : $entry->translations; foreach ( $translations as $i => $translation ) { $translation = wfPO::match_begin_and_end_newlines( $translation, $entry->plural ); $po[] = "msgstr[$i] " . wfPO::poify( $translation ); } } return implode( "\n", $po ); } public static function match_begin_and_end_newlines( $translation, $original ) { if ( '' === $translation ) { return $translation; } $original_begin = "\n" === substr( $original, 0, 1 ); $original_end = "\n" === substr( $original, -1 ); $translation_begin = "\n" === substr( $translation, 0, 1 ); $translation_end = "\n" === substr( $translation, -1 ); if ( $original_begin ) { if ( ! $translation_begin ) { $translation = "\n" . $translation; } } elseif ( $translation_begin ) { $translation = ltrim( $translation, "\n" ); } if ( $original_end ) { if ( ! $translation_end ) { $translation .= "\n"; } } elseif ( $translation_end ) { $translation = rtrim( $translation, "\n" ); } return $translation; } /** * @param string $filename * @return boolean */ function import_from_file( $filename ) { $f = fopen( $filename, 'r' ); if ( ! $f ) { return false; } $lineno = 0; while ( true ) { $res = $this->read_entry( $f, $lineno ); if ( ! $res ) { break; } if ( '' === $res['entry']->singular ) { $this->set_headers( $this->make_headers( $res['entry']->translations[0] ) ); } else { $this->add_entry( $res['entry'] ); } } wfPO::read_line( $f, 'clear' ); if ( false === $res ) { return false; } if ( ! $this->headers && ! $this->entries ) { return false; } return true; } /** * Helper function for read_entry * * @param string $context * @return bool */ protected static function is_final( $context ) { return ( 'msgstr' === $context ) || ( 'msgstr_plural' === $context ); } /** * @param resource $f * @param int $lineno * @return null|false|array */ function read_entry( $f, $lineno = 0 ) { $entry = new wfTranslation_Entry(); // Where were we in the last step. // Can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural. $context = ''; $msgstr_index = 0; while ( true ) { $lineno++; $line = wfPO::read_line( $f ); if ( ! $line ) { if ( feof( $f ) ) { if ( self::is_final( $context ) ) { break; } elseif ( ! $context ) { // We haven't read a line and EOF came. return null; } else { return false; } } else { return false; } } if ( "\n" === $line ) { continue; } $line = trim( $line ); if ( preg_match( '/^#/', $line, $m ) ) { // The comment is the start of a new entry. if ( self::is_final( $context ) ) { wfPO::read_line( $f, 'put-back' ); $lineno--; break; } // Comments have to be at the beginning. if ( $context && 'comment' !== $context ) { return false; } // Add comment. $this->add_comment_to_entry( $entry, $line ); } elseif ( preg_match( '/^msgctxt\s+(".*")/', $line, $m ) ) { if ( self::is_final( $context ) ) { wfPO::read_line( $f, 'put-back' ); $lineno--; break; } if ( $context && 'comment' !== $context ) { return false; } $context = 'msgctxt'; $entry->context .= wfPO::unpoify( $m[1] ); } elseif ( preg_match( '/^msgid\s+(".*")/', $line, $m ) ) { if ( self::is_final( $context ) ) { wfPO::read_line( $f, 'put-back' ); $lineno--; break; } if ( $context && 'msgctxt' !== $context && 'comment' !== $context ) { return false; } $context = 'msgid'; $entry->singular .= wfPO::unpoify( $m[1] ); } elseif ( preg_match( '/^msgid_plural\s+(".*")/', $line, $m ) ) { if ( 'msgid' !== $context ) { return false; } $context = 'msgid_plural'; $entry->is_plural = true; $entry->plural .= wfPO::unpoify( $m[1] ); } elseif ( preg_match( '/^msgstr\s+(".*")/', $line, $m ) ) { if ( 'msgid' !== $context ) { return false; } $context = 'msgstr'; $entry->translations = array( wfPO::unpoify( $m[1] ) ); } elseif ( preg_match( '/^msgstr\[(\d+)\]\s+(".*")/', $line, $m ) ) { if ( 'msgid_plural' !== $context && 'msgstr_plural' !== $context ) { return false; } $context = 'msgstr_plural'; $msgstr_index = $m[1]; $entry->translations[ $m[1] ] = wfPO::unpoify( $m[2] ); } elseif ( preg_match( '/^".*"$/', $line ) ) { $unpoified = wfPO::unpoify( $line ); switch ( $context ) { case 'msgid': $entry->singular .= $unpoified; break; case 'msgctxt': $entry->context .= $unpoified; break; case 'msgid_plural': $entry->plural .= $unpoified; break; case 'msgstr': $entry->translations[0] .= $unpoified; break; case 'msgstr_plural': $entry->translations[ $msgstr_index ] .= $unpoified; break; default: return false; } } else { return false; } } $have_translations = false; foreach ( $entry->translations as $t ) { if ( $t || ( '0' === $t ) ) { $have_translations = true; break; } } if ( false === $have_translations ) { $entry->translations = array(); } return array( 'entry' => $entry, 'lineno' => $lineno, ); } /** * @param resource $f * @param string $action * @return boolean */ function read_line( $f, $action = 'read' ) { static $last_line = ''; static $use_last_line = false; if ( 'clear' === $action ) { $last_line = ''; return true; } if ( 'put-back' === $action ) { $use_last_line = true; return true; } $line = $use_last_line ? $last_line : fgets( $f ); $line = ( "\r\n" === substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line; $last_line = $line; $use_last_line = false; return $line; } /** * @param wfTranslation_Entry $entry * @param string $po_comment_line */ function add_comment_to_entry( &$entry, $po_comment_line ) { $first_two = substr( $po_comment_line, 0, 2 ); $comment = trim( substr( $po_comment_line, 2 ) ); if ( '#:' === $first_two ) { $entry->references = array_merge( $entry->references, preg_split( '/\s+/', $comment ) ); } elseif ( '#.' === $first_two ) { $entry->extracted_comments = trim( $entry->extracted_comments . "\n" . $comment ); } elseif ( '#,' === $first_two ) { $entry->flags = array_merge( $entry->flags, preg_split( '/,\s*/', $comment ) ); } else { $entry->translator_comments = trim( $entry->translator_comments . "\n" . $comment ); } } /** * @param string $s * @return string */ public static function trim_quotes( $s ) { if ( '"' === substr( $s, 0, 1 ) ) { $s = substr( $s, 1 ); } if ( '"' === substr( $s, -1, 1 ) ) { $s = substr( $s, 0, -1 ); } return $s; } } endif; PK t�}\x=%� � wfWAFUserIPRange.phpnu �[��� <?php if (!defined('WFWAF_RUN_COMPLETE')) { /** * */ class wfWAFUserIPRange { /** * @var string|null */ private $ip_string; /** * @param string|null $ip_string */ public function __construct($ip_string = null) { $this->setIPString($ip_string); } public function isIPInRange($ip) { $ip_string = $this->getIPString(); if (strpos($ip_string, '/') !== false) { //CIDR range -- 127.0.0.1/24 return wfWAFUtils::subnetContainsIP($ip_string, $ip); } else if (strpos($ip_string, '[') !== false) //Bracketed range -- 127.0.0.[1-100] { // IPv4 range if (strpos($ip_string, '.') !== false && strpos($ip, '.') !== false) { // IPv4-mapped-IPv6 if (preg_match('/:ffff:([^:]+)$/i', $ip_string, $matches)) { $ip_string = $matches[1]; } if (preg_match('/:ffff:([^:]+)$/i', $ip, $matches)) { $ip = $matches[1]; } // Range check if (preg_match('/\[\d+\-\d+\]/', $ip_string)) { $IPparts = explode('.', $ip); $whiteParts = explode('.', $ip_string); $mismatch = false; if (count($whiteParts) != 4 || count($IPparts) != 4) { return false; } for ($i = 0; $i <= 3; $i++) { if (preg_match('/^\[(\d+)\-(\d+)\]$/', $whiteParts[$i], $m)) { if ($IPparts[$i] < $m[1] || $IPparts[$i] > $m[2]) { $mismatch = true; } } else if ($whiteParts[$i] != $IPparts[$i]) { $mismatch = true; } } if ($mismatch === false) { return true; // Is whitelisted because we did not get a mismatch } } else if ($ip_string == $ip) { return true; } // IPv6 range } else if (strpos($ip_string, ':') !== false && strpos($ip, ':') !== false) { $ip = strtolower(wfWAFUtils::expandIPv6Address($ip)); $ip_string = strtolower(self::expandIPv6Range($ip_string)); if (preg_match('/\[[a-f0-9]+\-[a-f0-9]+\]/i', $ip_string)) { $IPparts = explode(':', $ip); $whiteParts = explode(':', $ip_string); $mismatch = false; if (count($whiteParts) != 8 || count($IPparts) != 8) { return false; } for ($i = 0; $i <= 7; $i++) { if (preg_match('/^\[([a-f0-9]+)\-([a-f0-9]+)\]$/i', $whiteParts[$i], $m)) { $ip_group = hexdec($IPparts[$i]); $range_group_from = hexdec($m[1]); $range_group_to = hexdec($m[2]); if ($ip_group < $range_group_from || $ip_group > $range_group_to) { $mismatch = true; break; } } else if ($whiteParts[$i] != $IPparts[$i]) { $mismatch = true; break; } } if ($mismatch === false) { return true; // Is whitelisted because we did not get a mismatch } } else if ($ip_string == $ip) { return true; } } } else if (strpos($ip_string, '-') !== false) { //Linear range -- 127.0.0.1 - 127.0.1.100 list($ip1, $ip2) = explode('-', $ip_string); $ip1N = wfWAFUtils::inet_pton($ip1); $ip2N = wfWAFUtils::inet_pton($ip2); $ipN = wfWAFUtils::inet_pton($ip); return (strcmp($ip1N, $ipN) <= 0 && strcmp($ip2N, $ipN) >= 0); } else { //Treat as a literal IP $ip1 = wfWAFUtils::inet_pton($ip_string); $ip2 = wfWAFUtils::inet_pton($ip); if ($ip1 !== false && $ip1 == $ip2) { return true; } } return false; } private static function repeatString($string, $count) { if ($count <= 0) return ''; return str_repeat($string, $count); } /** * Expand a compressed printable range representation of an IPv6 address. * * @todo Hook up exceptions for better error handling. * @todo Allow IPv4 mapped IPv6 addresses (::ffff:192.168.1.1). * @param string $ip_range * @return string */ public static function expandIPv6Range($ip_range) { $colon_count = substr_count($ip_range, ':'); $dbl_colon_count = substr_count($ip_range, '::'); if ($dbl_colon_count > 1) { return false; } $dbl_colon_pos = strpos($ip_range, '::'); if ($dbl_colon_pos !== false) { $ip_range = str_replace('::', self::repeatString(':0000', (($dbl_colon_pos === 0 || $dbl_colon_pos === strlen($ip_range) - 2) ? 9 : 8) - $colon_count) . ':', $ip_range); $ip_range = trim($ip_range, ':'); } $colon_count = substr_count($ip_range, ':'); if ($colon_count != 7) { return false; } $groups = explode(':', $ip_range); $expanded = ''; foreach ($groups as $group) { if (preg_match('/\[([a-f0-9]{1,4})\-([a-f0-9]{1,4})\]/i', $group, $matches)) { $expanded .= sprintf('[%s-%s]', str_pad(strtolower($matches[1]), 4, '0', STR_PAD_LEFT), str_pad(strtolower($matches[2]), 4, '0', STR_PAD_LEFT)) . ':'; } else if (preg_match('/[a-f0-9]{1,4}/i', $group)) { $expanded .= str_pad(strtolower($group), 4, '0', STR_PAD_LEFT) . ':'; } else { return false; } } return trim($expanded, ':'); } /** * @return bool */ public function isValidRange() { return $this->isValidCIDRRange() || $this->isValidBracketedRange() || $this->isValidLinearRange() || filter_var($this->getIPString(), FILTER_VALIDATE_IP) !== false; } public function isValidCIDRRange() { //e.g., 192.0.2.1/24 $ip_string = $this->getIPString(); if (preg_match('/[^0-9a-f:\/\.]/i', $ip_string)) { return false; } $components = explode('/', $ip_string); if (count($components) != 2) { return false; } list($ip, $prefix) = $components; if (filter_var($ip, FILTER_VALIDATE_IP) === false) { return false; } if (!preg_match('/^\d+$/', $prefix)) { return false; } if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { if ($prefix < 0 || $prefix > 32) { return false; } } else { if ($prefix < 1 || $prefix > 128) { return false; } } return true; } public function isValidBracketedRange() { //e.g., 192.0.2.[1-10] $ip_string = $this->getIPString(); if (preg_match('/[^0-9a-f:\.\[\]\-]/i', $ip_string)) { return false; } if (strpos($ip_string, '.') !== false) { //IPv4 if (preg_match_all('/(\d+)/', $ip_string, $matches) > 0) { foreach ($matches[1] as $match) { $group = (int) $match; if ($group > 255 || $group < 0) { return false; } } } $group_regex = '([0-9]{1,3}|\[[0-9]{1,3}\-[0-9]{1,3}\])'; return preg_match('/^' . str_repeat("{$group_regex}\\.", 3) . $group_regex . '$/i', $ip_string) > 0; } //IPv6 if (strpos($ip_string, '::') !== false) { $ip_string = self::expandIPv6Range($ip_string); } if (!$ip_string) { return false; } $group_regex = '([a-f0-9]{1,4}|\[[a-f0-9]{1,4}\-[a-f0-9]{1,4}\])'; return preg_match('/^' . str_repeat("$group_regex:", 7) . $group_regex . '$/i', $ip_string) > 0; } public function isValidLinearRange() { //e.g., 192.0.2.1-192.0.2.100 $ip_string = $this->getIPString(); if (preg_match('/[^0-9a-f:\.\-]/i', $ip_string)) { return false; } list($ip1, $ip2) = explode("-", $ip_string); if (filter_var($ip1, FILTER_VALIDATE_IP) === false || filter_var($ip2, FILTER_VALIDATE_IP) === false) { return false; } $ip1N = wfWAFUtils::inet_pton($ip1); $ip2N = wfWAFUtils::inet_pton($ip2); if ($ip1N === false || $ip2N === false) { return false; } return strcmp($ip1N, $ip2N) <= 0; } protected function _sanitizeIPRange($ip_string) { $ip_string = preg_replace('/\s/', '', $ip_string); //Strip whitespace $ip_string = preg_replace('/[\\x{2013}-\\x{2015}]/u', '-', $ip_string); //Non-hyphen dashes to hyphen $ip_string = strtolower($ip_string); if (preg_match('/^\d+-\d+$/', $ip_string)) { //v5 32 bit int style format list($start, $end) = explode('-', $ip_string); $start = long2ip($start); $end = long2ip($end); $ip_string = "{$start}-{$end}"; } return $ip_string; } /** * @return string|null */ public function getIPString() { return $this->ip_string; } /** * @param string|null $ip_string */ public function setIPString($ip_string) { $this->ip_string = $this->_sanitizeIPRange($ip_string); } } }PK v�}\�i y�N �N wfWAFIPBlocksController.phpnu �[��� <?php if (!defined('WFWAF_RUN_COMPLETE')) { require_once __DIR__ . '/../vendor/wordfence/wf-waf/src/lib/shutdown.php'; class wfWAFIPBlocksController { const WFWAF_BLOCK_UAREFIPRANGE = 'UA/Referrer/IP Range not allowed'; const WFWAF_BLOCK_COUNTRY = 'blocked access via country blocking'; const WFWAF_BLOCK_COUNTRY_REDIR = 'blocked access via country blocking and redirected to URL'; const WFWAF_BLOCK_COUNTRY_BYPASS_REDIR = 'redirected to bypass URL'; const WFWAF_BLOCK_WFSN = 'Blocked by Wordfence Security Network'; const WFWAF_BLOCK_BADPOST = 'POST received with blank user-agent and referer'; const WFWAF_BLOCK_BANNEDURL = 'Accessed a banned URL.'; const WFWAF_BLOCK_FAKEGOOGLE = 'Fake Google crawler automatically blocked'; const WFWAF_BLOCK_LOGINSEC = 'Blocked by login security setting.'; const WFWAF_BLOCK_LOGINSEC_FORGOTPASSWD = 'Exceeded the maximum number of tries to recover their password'; //substring search const WFWAF_BLOCK_LOGINSEC_FAILURES = 'Exceeded the maximum number of login failures'; //substring search const WFWAF_BLOCK_THROTTLEGLOBAL = 'Exceeded the maximum global requests per minute for crawlers or humans.'; const WFWAF_BLOCK_THROTTLESCAN = 'Exceeded the maximum number of 404 requests per minute for a known security vulnerability.'; const WFWAF_BLOCK_THROTTLECRAWLER = 'Exceeded the maximum number of requests per minute for crawlers.'; const WFWAF_BLOCK_THROTTLECRAWLERNOTFOUND = 'Exceeded the maximum number of page not found errors per minute for a crawler.'; const WFWAF_BLOCK_THROTTLEHUMAN = 'Exceeded the maximum number of page requests per minute for humans.'; const WFWAF_BLOCK_THROTTLEHUMANNOTFOUND = 'Exceeded the maximum number of page not found errors per minute for humans.'; protected static $_currentController = null; public static function currentController() { if (self::$_currentController === null) { self::$_currentController = new wfWAFIPBlocksController(); } return self::$_currentController; } public static function setCurrentController($currentController) { self::$_currentController = $currentController; } /** * Schedules a config sync to happen at the end of the current process's execution. */ public static function setNeedsSynchronizeConfigSettings() { static $willSynchronize = false; if (!$willSynchronize) { $willSynchronize = true; wfShutdownRegistry::getDefaultInstance()->register('wfWAFIPBlocksController::synchronizeConfigSettings'); } } public static function synchronizeConfigSettings() { if (!class_exists('wfConfig') || !wfConfig::tableExists() || !wfWAF::getInstance()) { // Ensure this is only called when WordPress and the plugin are fully loaded return; } static $isSynchronizing = false; if ($isSynchronizing) { return; } $isSynchronizing = true; global $wpdb; $suppressed = $wpdb->suppress_errors(!(defined('WFWAF_DEBUG') && WFWAF_DEBUG)); // Pattern Blocks $blocks = wfBlock::patternBlocks(true); $patternBlocks = array(); foreach ($blocks as $b) { $patternBlocks[] = array('id' => $b->id, 'ipRange' => $b->ipRange, 'hostnamePattern' => $b->hostname, 'uaPattern' => $b->userAgent, 'refPattern' => $b->referrer, 'expiration' => $b->expiration); } // Country Blocks $countryBlocks = array(); $countryBlockEntries = wfBlock::countryBlocks(true); $countryBlocks['blocks'] = array(); foreach ($countryBlockEntries as $b) { $reason = __('Access from your area has been temporarily limited for security reasons', 'wordfence'); $countryBlocks['blocks'][] = array( 'id' => $b->id, 'countries' => $b->countries, 'blockLogin' => $b->blockLogin, 'blockSite' => $b->blockSite, 'reason' => $reason, 'expiration' => $b->expiration, ); } $countryBlocks['action'] = wfConfig::get('cbl_action', false); $countryBlocks['loggedInBlocked'] = wfConfig::get('cbl_loggedInBlocked', false); $countryBlocks['bypassRedirURL'] = wfConfig::get('cbl_bypassRedirURL', ''); $countryBlocks['bypassRedirDest'] = wfConfig::get('cbl_bypassRedirDest', ''); $countryBlocks['bypassViewURL'] = wfConfig::get('cbl_bypassViewURL', ''); $countryBlocks['redirURL'] = wfConfig::get('cbl_redirURL', ''); $countryBlocks['cookieVal'] = wfBlock::countryBlockingBypassCookieValue(); //Other Blocks $otherBlocks = array('blockedTime' => wfConfig::get('blockedTime', 0)); $otherBlockEntries = wfBlock::ipBlocks(true); $otherBlocks['blocks'] = array(); foreach ($otherBlockEntries as $b) { $reason = $b->reason; if ($b->type == wfBlock::TYPE_IP_MANUAL || $b->type == wfBlock::TYPE_IP_AUTOMATIC_PERMANENT) { $reason = __('Manual block by administrator', 'wordfence'); } $otherBlocks['blocks'][] = array( 'id' => $b->id, 'IP' => base64_encode(wfUtils::inet_pton($b->ip)), 'reason' => $reason, 'expiration' => $b->expiration, ); } //Lockouts $lockoutEntries = wfBlock::lockouts(true); $lockoutSecs = wfConfig::get('loginSec_lockoutMins') * 60; $lockouts = array('lockedOutTime' => $lockoutSecs, 'lockouts' => array()); foreach ($lockoutEntries as $l) { $lockouts['lockouts'][] = array( 'id' => $l->id, 'IP' => base64_encode(wfUtils::inet_pton($l->ip)), 'reason' => $l->reason, 'expiration' => $l->expiration, ); } // Save it try { $patternBlocksJSON = wfWAFUtils::json_encode($patternBlocks); wfWAF::getInstance()->getStorageEngine()->setConfig('patternBlocks', $patternBlocksJSON, 'synced'); $countryBlocksJSON = wfWAFUtils::json_encode($countryBlocks); wfWAF::getInstance()->getStorageEngine()->setConfig('countryBlocks', $countryBlocksJSON, 'synced'); $otherBlocksJSON = wfWAFUtils::json_encode($otherBlocks); wfWAF::getInstance()->getStorageEngine()->setConfig('otherBlocks', $otherBlocksJSON, 'synced'); $lockoutsJSON = wfWAFUtils::json_encode($lockouts); wfWAF::getInstance()->getStorageEngine()->setConfig('lockouts', $lockoutsJSON, 'synced'); wfWAF::getInstance()->getStorageEngine()->setConfig('advancedBlockingEnabled', wfConfig::get('firewallEnabled'), 'synced'); wfWAF::getInstance()->getStorageEngine()->setConfig('disableWAFIPBlocking', wfConfig::get('disableWAFIPBlocking'), 'synced'); } catch (Exception $e) { // Do nothing } $isSynchronizing = false; $wpdb->suppress_errors($suppressed); } /** * @param wfWAFRequest $request * @return bool|string If not blocked, returns false. Otherwise a string of the reason it was blocked or true. */ public function shouldBlockRequest($request) { // Checking the user whitelist is done before reaching this call $ip = $request->getIP(); //Check the system whitelist if ($this->checkForWhitelisted($ip)) { return false; } //Let the plugin handle these $wfFunc = $request->getQueryString('_wfsf'); if ($wfFunc == 'unlockEmail' || $wfFunc == 'unlockAccess') { // Can't check validity here, let it pass through to plugin level where it can return false; } $logHuman = $request->getQueryString('wordfence_lh'); if ($logHuman !== null) { return false; } //Start block checks $ipNum = wfWAFUtils::inet_pton($ip); $hostname = null; $ua = $request->getHeaders('User-Agent'); if ($ua === null) { $ua = ''; } $referer = $request->getHeaders('Referer'); if ($referer === null) { $referer = ''; } $isPaid = false; try { $isPaid = wfWAF::getInstance()->getStorageEngine()->getConfig('isPaid', null, 'synced'); $pluginABSPATH = wfWAF::getInstance()->getStorageEngine()->getConfig('pluginABSPATH', null, 'synced'); $patternBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('patternBlocks', null, 'synced'); $countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks', null, 'synced'); $otherBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('otherBlocks', null, 'synced'); $lockoutsJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('lockouts', null, 'synced'); } catch (Exception $e) { // Do nothing } if (isset($_SERVER['SCRIPT_FILENAME']) && (strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-admin/") === 0 || strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-content/") === 0 || strpos($_SERVER['SCRIPT_FILENAME'], $pluginABSPATH . "wp-includes/") === 0)) { return false; //Rely on WordPress's own access control and blocking at the plugin level } // Pattern Blocks from the Advanced Blocking page (IP Range, UA, Referer) $patternBlocks = @wfWAFUtils::json_decode($patternBlocksJSON, true); if (is_array($patternBlocks)) { // Instead of a long block of if/else statements, using bitshifting to generate an expected value and a found value $ipRangeOffset = 1; $uaPatternOffset = 2; $refPatternOffset = 3; foreach ($patternBlocks as $b) { $expectedBits = 0; $foundBits = 0; if (isset($b['expiration']) && $b['expiration'] < time() && $b['expiration'] != 0) { continue; } if (!empty($b['ipRange'])) { $expectedBits |= (1 << $ipRangeOffset); $range = new wfWAFUserIPRange($b['ipRange']); if ($range->isIPInRange($ip)) { $foundBits |= (1 << $ipRangeOffset); } } if (!empty($b['hostnamePattern'])) { $expectedBits |= (1 << $ipRangeOffset); if ($hostname === null) { $hostname = wfWAFUtils::reverseLookup($ip); } if (preg_match(wfWAFUtils::patternToRegex($b['hostnamePattern']), $hostname)) { $foundBits |= (1 << $ipRangeOffset); } } if (!empty($b['uaPattern'])) { $expectedBits |= (1 << $uaPatternOffset); if (wfWAFUtils::isUABlocked($b['uaPattern'], $ua)) { $foundBits |= (1 << $uaPatternOffset); } } if (!empty($b['refPattern'])) { $expectedBits |= (1 << $refPatternOffset); if (wfWAFUtils::isRefererBlocked($b['refPattern'], $referer)) { $foundBits |= (1 << $refPatternOffset); } } if ($foundBits === $expectedBits && $expectedBits > 0) { return array('action' => self::WFWAF_BLOCK_UAREFIPRANGE, 'id' => $b['id']); } } } // End Pattern Blocks // Country Blocking if ($isPaid) { $countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true); if (is_array($countryBlocks) && isset($countryBlocks['blocks'])) { $blocks = $countryBlocks['blocks']; foreach ($blocks as $b) { $blockedCountries = $b['countries']; $bareRequestURI = wfWAFUtils::extractBareURI($request->getURI()); $bareBypassRedirURI = wfWAFUtils::extractBareURI($countryBlocks['bypassRedirURL']); $skipCountryBlocking = false; if ($bareBypassRedirURI && $bareRequestURI == $bareBypassRedirURI) { // Run this before country blocking because even if the user isn't blocked we need to set the bypass cookie so they can bypass future blocks. if ($countryBlocks['bypassRedirDest']) { setcookie('wfCBLBypass', $countryBlocks['cookieVal'], time() + (86400 * 365), '/', null, $this->isFullSSL(), true); return array('action' => self::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR, 'id' => $b['id']); } } $bareBypassViewURI = wfWAFUtils::extractBareURI($countryBlocks['bypassViewURL']); if ($bareBypassViewURI && $bareBypassViewURI == $bareRequestURI) { setcookie('wfCBLBypass', $countryBlocks['cookieVal'], time() + (86400 * 365), '/', null, $this->isFullSSL(), true); $skipCountryBlocking = true; } $bypassCookieSet = false; $bypassCookie = $request->getCookies('wfCBLBypass'); if (isset($bypassCookie) && $bypassCookie == $countryBlocks['cookieVal']) { $bypassCookieSet = true; } if (!$skipCountryBlocking && $blockedCountries && !$bypassCookieSet) { $isAuthRequest = (strpos($bareRequestURI, '/wp-login.php') !== false); $isXMLRPC = (strpos($bareRequestURI, '/xmlrpc.php') !== false); $isUserLoggedIn = wfWAF::getInstance()->parseAuthCookie() !== false; // If everything is checked, make sure this always runs. if ($countryBlocks['loggedInBlocked'] && $b['blockLogin'] && $b['blockSite']) { if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; } } // Block logged in users. if ($countryBlocks['loggedInBlocked'] && $isUserLoggedIn) { if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; } } // Block the login form itself and any attempt to authenticate. if ($b['blockLogin'] && $isAuthRequest) { if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; } } // Block requests that aren't to the login page, xmlrpc.php, or a user already logged in. if ($b['blockSite'] && !$isAuthRequest && !$isXMLRPC && !$isUserLoggedIn) { if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; } } // XMLRPC is inaccesible when public portion of the site and auth is disabled. if ($b['blockLogin'] && $b['blockSite'] && $isXMLRPC) { if ($blocked = $this->checkForBlockedCountry($countryBlocks, $ip, $bareRequestURI)) { $blocked['id'] = $b['id']; return $blocked; } } // Any bypasses and other block possibilities will be checked at the plugin level once WordPress loads } } } } // End Country Blocking // Other Blocks $otherBlocks = @wfWAFUtils::json_decode($otherBlocksJSON, true); if (is_array($otherBlocks)) { $blocks = $otherBlocks['blocks']; $bareRequestURI = wfWAFUtils::extractBareURI($request->getURI()); $isAuthRequest = (stripos($bareRequestURI, '/wp-login.php') !== false); foreach ($blocks as $b) { if (isset($b['expiration']) && $b['expiration'] < time() && $b['expiration'] != 0) { continue; } if (base64_decode($b['IP']) != $ipNum) { continue; } if ($isAuthRequest && isset($b['wfsn']) && $b['wfsn']) { return array('action' => self::WFWAF_BLOCK_WFSN, 'id' => $b['id']); } return array('action' => (empty($b['reason']) ? '' : $b['reason']), 'id' => $b['id'], 'block' => true); } } // End Other Blocks // Lockouts $lockouts = @wfWAFUtils::json_decode($lockoutsJSON, true); if (is_array($lockouts)) { $lockouts = $lockouts['lockouts']; $isAuthRequest = (stripos($bareRequestURI, '/wp-login.php') !== false) || (stripos($bareRequestURI, '/xmlrpc.php') !== false); if ($isAuthRequest) { foreach ($lockouts as $l) { if (isset($l['expiration']) && $l['expiration'] < time()) { continue; } if (base64_decode($l['IP']) != $ipNum) { continue; } return array('action' => (empty($l['reason']) ? '' : $l['reason']), 'id' => $l['id'], 'lockout' => true); } } } // End Lockouts return false; } public function countryRedirURL($countryBlocks = null) { if (!isset($countryBlocks)) { try { $countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks', null, 'synced'); } catch (Exception $e) { return false; } } $countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true); if (is_array($countryBlocks)) { if ($countryBlocks['action'] == 'redir') { return $countryBlocks['redirURL']; } } return false; } public function countryBypassRedirURL($countryBlocks = null) { if (!isset($countryBlocks)) { try { $countryBlocksJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('countryBlocks', null, 'synced'); } catch (Exception $e) { return false; } } $countryBlocks = @wfWAFUtils::json_decode($countryBlocksJSON, true); if (is_array($countryBlocks)) { return $countryBlocks['bypassRedirDest']; } return false; } protected function checkForBlockedCountry($countryBlock, $ip, $bareRequestURI) { try { $homeURL = wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL', null, 'synced'); } catch (Exception $e) { //Do nothing } $bareRequestURI = rtrim($bareRequestURI, '/\\'); if ($country = $this->ip2Country($ip)) { $blocks = $countryBlock['blocks']; foreach ($blocks as $b) { foreach ($b['countries'] as $blocked) { if (strtoupper($blocked) == strtoupper($country)) { if ($countryBlock['action'] == 'redir') { $redirURL = $countryBlock['redirURL']; $eRedirHost = wfWAFUtils::extractHostname($redirURL); $isExternalRedir = false; if ($eRedirHost && $homeURL && $eRedirHost != wfWAFUtils::extractHostname($homeURL)) { $isExternalRedir = true; } if ((!$isExternalRedir) && rtrim(wfWAFUtils::extractBareURI($redirURL), '/\\') == $bareRequestURI){ //Is this the URI we want to redirect to, then don't block it //Do nothing } else { return array('action' => self::WFWAF_BLOCK_COUNTRY_REDIR); } } else { return array('action' => self::WFWAF_BLOCK_COUNTRY); } } } } } return false; } protected function checkForWhitelisted($ip) { try { $pluginABSPATH = wfWAF::getInstance()->getStorageEngine()->getConfig('pluginABSPATH', null, 'synced'); $serverIPsJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('serverIPs', null, 'synced'); $whitelistedServiceIPsJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('whitelistedServiceIPs', null, 'synced'); } catch (Exception $e) { // Do nothing } $serverIPs = @wfWAFUtils::json_decode($serverIPsJSON, true); if (is_array($serverIPs)) { if ( (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == realpath($pluginABSPATH . DIRECTORY_SEPARATOR . 'wp-cron.php')) || //Safe -- plugin will do a final check to make sure the cron constant is defined (!empty($_GET['wordfence_syncAttackData'])) //Safe but plugin will do a final check to make sure it runs ) { foreach ($serverIPs as $testIP) { if (wfWAFUtils::inet_pton($ip) == wfWAFUtils::inet_pton($testIP)) { return true; } } } } $whitelistedServiceIPs = @wfWAFUtils::json_decode($whitelistedServiceIPsJSON, true); if (is_array($whitelistedServiceIPs)) { $wfIPWhitelist = $whitelistedServiceIPs; } else { $wordfenceLib = realpath(dirname(__FILE__) . '/../lib'); include($wordfenceLib . '/wfIPWhitelist.php'); /** @var array $wfIPWhitelist */ } foreach ($wfIPWhitelist as $group) { foreach ($group as $subnet) { if ($subnet instanceof wfWAFUserIPRange) { //Not currently reached if ($subnet->isIPInRange($ip)) { return true; } } elseif (wfWAFUtils::subnetContainsIP($subnet, $ip)) { return true; } } } return false; } protected function ip2Country($ip) { /** * It's possible this class is already loaded from a different installation of the plugin * by the time this is reached. See wfUtils::requireIpLocator for additional details. */ if (!class_exists('wfIpLocator')) require_once __DIR__ . '/../lib/wfIpLocator.php'; return wfIpLocator::getInstance()->getCountryCode($ip); } /** * Returns whether or not the site should be treated as if it's full-time SSL. * * @return bool */ protected function isFullSSL() { try { $is_ssl = false; //This is the same code from WP modified so we can use it here if ( isset( $_SERVER['HTTPS'] ) ) { if ( 'on' == strtolower( $_SERVER['HTTPS'] ) ) { $is_ssl = true; } if ( '1' == $_SERVER['HTTPS'] ) { $is_ssl = true; } } elseif ( isset($_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ) { $is_ssl = true; } $homeURL = wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL', null, 'synced'); return $is_ssl && parse_url($homeURL, PHP_URL_SCHEME) === 'https'; } catch (Exception $e) { //Do nothing } return false; } } }PK w�}\ob b .htaccessnu �[��� <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_URI} \.php$ RewriteRule .* - [F,L,NC] </IfModule> <IfModule !mod_rewrite.c> <FilesMatch "\.php$"> <IfModule mod_authz_core.c> Require all denied </IfModule> <IfModule !mod_authz_core.c> Order deny,allow Deny from all </IfModule> </FilesMatch> </IfModule>PK x�}\��sV V dummy.phpnu �[��� <?php /** * A dummy WAF implementation that can be used if initialization of the actual WAF failures */ class wfDummyWaf extends wfWAF { public function __construct() { parent::__construct(new wfDummyWafRequest(), new wfDummyWafStorageEngine()); } } class wfDummyWafRequest implements wfWAFRequestInterface { public function getBody() { return null; } public function getRawBody() { return null; } public function getMd5Body() { return null; } public function getJsonBody() { return null; } public function getQueryString() { return null; } public function getMd5QueryString() { return null; } public function getHeaders() { return null; } public function getCookies() { return null; } public function getFiles() { return null; } public function getFileNames() { return null; } public function getHost() { return null; } public function getURI() { return null; } public function setMetadata($metadata) { } public function getMetadata() { return null; } public function getPath() { return null; } public function getIP() { return null; } public function getMethod() { return null; } public function getProtocol() { return null; } public function getAuth() { return null; } public function getTimestamp() { return null; } public function __toString() { return ''; } } class wfDummyWafStorageEngine implements wfWAFStorageInterface { public function hasPreviousAttackData($olderThan) { return false; } public function hasNewerAttackData($newerThan) { return false; } public function getAttackData() { return null; } public function getAttackDataArray() { return array(); } public function getNewestAttackDataArray($newerThan) { return array(); } public function truncateAttackData() { } public function logAttack($failedRules, $failedParamKey, $failedParamValue, $request, $_ = null) { } public function blockIP($timestamp, $ip) { } public function isIPBlocked($ip) { return false; } public function purgeIPBlocks($types = wfWAFStorageInterface::IP_BLOCKS_ALL) { } public function getConfig($key, $default = null, $category = '') { if ($key === 'wafStatus') return 'disabled'; return $default; } public function setConfig($key, $value, $category = '') { } public function unsetConfig($key, $category = '') { } public function uninstall() { } public function isInLearningMode() { return false; } public function isDisabled() { return true; } public function getRulesDSLCacheFile() { return null; } public function isAttackDataFull() { return false; } public function vacuum() { } public function getRules() { return array(); } public function setRules($rules) { } public function needsInitialRules() { return false; } public function getDescription() { return 'Dummy Storage Engine'; } }PK y�}\HE�$� $� bootstrap.phpnu �[��� <?php /* php_value auto_prepend_file ~/wp-content/plugins/wordfence/waf/bootstrap.php */ if (!defined('WFWAF_RUN_COMPLETE')) { if (!defined('WFWAF_AUTO_PREPEND')) { define('WFWAF_AUTO_PREPEND', true); } if (!defined('WF_IS_WP_ENGINE')) { define('WF_IS_WP_ENGINE', isset($_SERVER['IS_WPE'])); } if (!defined('WF_IS_FLYWHEEL')) { define('WF_IS_FLYWHEEL', isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Flywheel/') === 0); } if (!defined('WF_IS_PRESSABLE')) { define('WF_IS_PRESSABLE', (defined('IS_ATOMIC') && IS_ATOMIC) || (defined('IS_PRESSABLE') && IS_PRESSABLE)); } require(dirname(__FILE__) . '/../lib/wfVersionSupport.php'); /** * @var string $wfPHPDeprecatingVersion * @var string $wfPHPMinimumVersion */ if (!defined('WF_PHP_UNSUPPORTED')) { define('WF_PHP_UNSUPPORTED', version_compare(PHP_VERSION, $wfPHPMinimumVersion, '<')); } if (WF_PHP_UNSUPPORTED) { return; } require_once(dirname(__FILE__) . '/wfWAFUserIPRange.php'); require_once(dirname(__FILE__) . '/wfWAFIPBlocksController.php'); require_once(dirname(__FILE__) . '/../vendor/wordfence/wf-waf/src/init.php'); class wfWAFWordPressRequest extends wfWAFRequest { /** * @param wfWAFRequest|null $request * @return wfWAFRequest */ public static function createFromGlobals($request = null) { if (version_compare(phpversion(), '5.3.0') >= 0) { $class = get_called_class(); $request = new $class(); } else { $request = new self(); } return parent::createFromGlobals($request); } public function getIP() { static $theIP = null; if (isset($theIP)) { return $theIP; } $ips = array(); $howGet = wfWAF::getInstance()->getStorageEngine()->getConfig('howGetIPs', null, 'synced'); if ($howGet) { if (is_string($howGet) && is_array($_SERVER) && array_key_exists($howGet, $_SERVER)) { $ips[] = array($_SERVER[$howGet], $howGet); } if ($howGet != 'REMOTE_ADDR') { $ips[] = array((is_array($_SERVER) && array_key_exists('REMOTE_ADDR', $_SERVER)) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1', 'REMOTE_ADDR'); } } else { $recommendedField = wfWAF::getInstance()->getStorageEngine()->getConfig('detectProxyRecommendation', null, 'synced'); if (!empty($recommendedField) && $recommendedField != 'UNKNOWN' && $recommendedField != 'DEFERRED') { if (isset($_SERVER[$recommendedField])) { $ips[] = array($_SERVER[$recommendedField], $recommendedField); } } $ips[] = array((is_array($_SERVER) && array_key_exists('REMOTE_ADDR', $_SERVER)) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1', 'REMOTE_ADDR'); if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips[] = array($_SERVER['HTTP_X_FORWARDED_FOR'], 'HTTP_X_FORWARDED_FOR'); } if (isset($_SERVER['HTTP_X_REAL_IP'])) { $ips[] = array($_SERVER['HTTP_X_REAL_IP'], 'HTTP_X_REAL_IP'); } } $cleanedIP = $this->_getCleanIPAndServerVar($ips); if (is_array($cleanedIP)) { list($ip, $variable) = $cleanedIP; $theIP = $ip; return $ip; } $theIP = $cleanedIP; return $cleanedIP; } /** * Expects an array of items. The items are either IPs or IPs separated by comma, space or tab. Or an array of IP's. * We then examine all IP's looking for a public IP and storing private IP's in an array. If we find no public IPs we return the first private addr we found. * * @param array $arr * @return bool|mixed */ private function _getCleanIPAndServerVar($arr) { $privates = array(); //Store private addrs until end as last resort. foreach ($arr as $entry) { list($item, $var) = $entry; if (is_array($item)) { foreach ($item as $j) { // try verifying the IP is valid before stripping the port off if (!$this->_isValidIP($j)) { $j = preg_replace('/:\d+$/', '', $j); //Strip off port } if ($this->_isValidIP($j)) { if ($this->_isIPv6MappedIPv4($j)) { $j = wfWAFUtils::inet_ntop(wfWAFUtils::inet_pton($j)); } if ($this->_isPrivateIP($j)) { $privates[] = array($j, $var); } else { return array($j, $var); } } } continue; //This was an array so we can skip to the next item } $skipToNext = false; $trustedProxyConfig = wfWAF::getInstance()->getStorageEngine()->getConfig('howGetIPs_trusted_proxies_unified', null, 'synced'); $trustedProxies = $trustedProxyConfig === null ? array() : explode("\n", $trustedProxyConfig); foreach (array(',', ' ', "\t") as $char) { if (strpos($item, $char) !== false) { $sp = explode($char, $item); $sp = array_reverse($sp); foreach ($sp as $index => $j) { $j = trim($j); if (!$this->_isValidIP($j)) { $j = preg_replace('/:\d+$/', '', $j); //Strip off port } if ($this->_isValidIP($j)) { if ($this->_isIPv6MappedIPv4($j)) { $j = wfWAFUtils::inet_ntop(wfWAFUtils::inet_pton($j)); } foreach ($trustedProxies as $proxy) { if (!empty($proxy)) { if (wfWAFUtils::subnetContainsIP($proxy, $j) && $index < count($sp) - 1) { continue 2; } } } if ($this->_isPrivateIP($j)) { $privates[] = array($j, $var); } else { return array($j, $var); } } } $skipToNext = true; break; } } if ($skipToNext){ continue; } //Skip to next item because this one had a comma, space or tab so was delimited and we didn't find anything. if (!$this->_isValidIP($item)) { $item = preg_replace('/:\d+$/', '', $item); //Strip off port } if ($this->_isValidIP($item)) { if ($this->_isIPv6MappedIPv4($item)) { $item = wfWAFUtils::inet_ntop(wfWAFUtils::inet_pton($item)); } if ($this->_isPrivateIP($item)) { $privates[] = array($item, $var); } else { return array($item, $var); } } } if (sizeof($privates) > 0) { return $privates[0]; //Return the first private we found so that we respect the order the IP's were passed to this function. } return false; } /** * @param string $ip * @return bool */ private function _isValidIP($ip) { return filter_var($ip, FILTER_VALIDATE_IP) !== false; } /** * @param string $ip * @return bool */ private function _isIPv6MappedIPv4($ip) { return preg_match('/^(?:\:(?:\:0{1,4}){0,4}\:|(?:0{1,4}\:){5})ffff\:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/i', $ip) > 0; } /** * @param string $addr Should be in dot or colon notation (127.0.0.1 or ::1) * @return bool */ private function _isPrivateIP($ip) { // Run this through the preset list for IPv4 addresses. if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) { $wordfenceLib = realpath(dirname(__FILE__) . '/../lib'); include($wordfenceLib . '/wfIPWhitelist.php'); // defines $wfIPWhitelist $private = $wfIPWhitelist['private']; foreach ($private as $a) { if (wfWAFUtils::subnetContainsIP($a, $ip)) { return true; } } } return filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6) !== false && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false; } } class wfWAFWordPressObserver extends wfWAFBaseObserver { private $waf; public function __construct($waf){ $this->waf=$waf; } public function beforeRunRules() { // Whitelisted URLs (in WAF config) $whitelistedURLs = wfWAF::getInstance()->getStorageEngine()->getConfig('whitelistedURLs', null, 'livewaf'); if ($whitelistedURLs) { $whitelistPattern = ""; foreach ($whitelistedURLs as $whitelistedURL) { $whitelistPattern .= preg_replace('/\\\\\*/', '.*?', preg_quote($whitelistedURL, '/')) . '|'; } $whitelistPattern = '/^(?:' . wfWAFUtils::substr($whitelistPattern, 0, -1) . ')$/i'; wfWAFRule::create(wfWAF::getInstance(), 0x8000000, 'rule', 'whitelist', 0, 'User Supplied Allowlisted URL', 'allow', new wfWAFRuleComparisonGroup( new wfWAFRuleComparison(wfWAF::getInstance(), 'match', $whitelistPattern, array( 'request.uri', )) ) )->evaluate(); } // Whitelisted IPs (Wordfence config) $whitelistedIPs = wfWAF::getInstance()->getStorageEngine()->getConfig('whitelistedIPs', null, 'synced'); if ($whitelistedIPs) { if (!is_array($whitelistedIPs)) { $whitelistedIPs = explode(',', $whitelistedIPs); } foreach ($whitelistedIPs as $whitelistedIP) { $ipRange = new wfWAFUserIPRange($whitelistedIP); if ($ipRange->isIPInRange(wfWAF::getInstance()->getRequest()->getIP())) { throw new wfWAFAllowException('Wordfence allowlisted IP.'); } } } // Check plugin blocking if ($result = wfWAF::getInstance()->willPerformFinalAction(wfWAF::getInstance()->getRequest())) { if ($result === true) { $result = 'Not available'; } // Should not happen but can if the reason in the blocks table is empty wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('finalAction' => $result))); } } public function afterRunRules() { //Blacklist if (!wfWAF::getInstance()->getStorageEngine()->getConfig('disableWAFBlacklistBlocking')) { $blockedPrefixes = wfWAF::getInstance()->getStorageEngine()->getConfig('blockedPrefixes', null, 'transient'); if ($blockedPrefixes && wfWAF::getInstance()->getStorageEngine()->getConfig('isPaid', null, 'synced')) { $blockedPrefixes = base64_decode($blockedPrefixes); if ($this->_prefixListContainsIP($blockedPrefixes, wfWAF::getInstance()->getRequest()->getIP()) !== false) { $allowedCacheJSON = wfWAF::getInstance()->getStorageEngine()->getConfig('blacklistAllowedCache', '', 'transient'); $allowedCache = @json_decode($allowedCacheJSON, true); if (!is_array($allowedCache)) { $allowedCache = array(); } $cacheTest = base64_encode(wfWAFUtils::inet_pton(wfWAF::getInstance()->getRequest()->getIP())); if (!in_array($cacheTest, $allowedCache)) { $guessSiteURL = sprintf('%s://%s/', wfWAF::getInstance()->getRequest()->getProtocol(), wfWAF::getInstance()->getRequest()->getHost()); try { $request = new wfWAFHTTP(); $response = wfWAFHTTP::get(WFWAF_API_URL_SEC . "?" . http_build_query(array( 'action' => 'is_ip_blacklisted', 'ip' => wfWAF::getInstance()->getRequest()->getIP(), 'k' => wfWAF::getInstance()->getStorageEngine()->getConfig('apiKey', null, 'synced'), 's' => wfWAF::getInstance()->getStorageEngine()->getConfig('siteURL', null, 'synced') ? wfWAF::getInstance()->getStorageEngine()->getConfig('siteURL', null, 'synced') : $guessSiteURL, 'h' => wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL', null, 'synced') ? wfWAF::getInstance()->getStorageEngine()->getConfig('homeURL', null, 'synced') : $guessSiteURL, 't' => microtime(true), 'lang' => wfWAF::getInstance()->getStorageEngine()->getConfig('WPLANG', null, 'synced'), ), '', '&'), $request); if ($response instanceof wfWAFHTTPResponse && $response->getBody()) { $jsonData = wfWAFUtils::json_decode($response->getBody(), true); if (is_array($jsonData) && array_key_exists('data', $jsonData)) { if (preg_match('/^block:(\d+)$/i', $jsonData['data'], $matches)) { wfWAF::getInstance()->getStorageEngine()->blockIP((int)$matches[1] + time(), wfWAF::getInstance()->getRequest()->getIP(), wfWAFStorageInterface::IP_BLOCKS_BLACKLIST); $e = new wfWAFBlockException(); $e->setFailedRules(array('blocked')); $e->setRequest(wfWAF::getInstance()->getRequest()); throw $e; } else { //Allowed, cache until the next prefix list refresh $allowedCache[] = $cacheTest; wfWAF::getInstance()->getStorageEngine()->setConfig('blacklistAllowedCache', json_encode($allowedCache), 'transient'); } } } } catch (wfWAFHTTPTransportException $e) { error_log($e->getMessage()); } } } } } if ($reason = wfWAF::getInstance()->getRequest()->getMetadata('finalAction')) { $e = new wfWAFBlockException($reason['action']); $e->setRequest(wfWAF::getInstance()->getRequest()); throw $e; } } private function _prefixListContainsIP($prefixList, $ip) { $size = ord(wfWAFUtils::substr($prefixList, 0, 1)); $sha256 = hash('sha256', wfWAFUtils::inet_pton($ip), true); $p = wfWAFUtils::substr($sha256, 0, $size); $count = ceil((wfWAFUtils::strlen($prefixList) - 1) / $size); $low = 0; $high = $count - 1; while ($low <= $high) { $mid = (int) (($high + $low) / 2); $val = wfWAFUtils::substr($prefixList, 1 + $mid * $size, $size); $cmp = strcmp($val, $p); if ($cmp < 0) { $low = $mid + 1; } else if ($cmp > 0) { $high = $mid - 1; } else { return $mid; } } return false; } } /** * */ class wfWAFWordPress extends wfWAF { /** @var wfWAFRunException */ private $learningModeAttackException; /** * @param wfWAFBlockException $e * @param int $httpCode */ public function blockAction($e, $httpCode = 403, $redirect = false, $template = null) { $failedRules = $e->getFailedRules(); if (!is_array($failedRules)) { $failedRules = array(); } if ($this->isInLearningMode() && !$e->getRequest()->getMetadata('finalAction') && !in_array('blocked', $failedRules)) { register_shutdown_function(array( $this, 'whitelistFailedRulesIfNot404', )); $this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest()); $this->setLearningModeAttackException($e); } else { if (empty($failedRules)) { $finalAction = $e->getRequest()->getMetadata('finalAction'); if (is_array($finalAction)) { $isLockedOut = isset($finalAction['lockout']) && $finalAction['lockout']; $finalAction = $finalAction['action']; if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_REDIR) { $redirect = wfWAFIPBlocksController::currentController()->countryRedirURL(); } else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR) { $redirect = wfWAFIPBlocksController::currentController()->countryBypassRedirURL(); } else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_UAREFIPRANGE) { wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Advanced blocking in effect.', '503Time' => 3600))); $httpCode = 503; } else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY) { wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Access from your area has been temporarily limited for security reasons.', '503Time' => 3600))); $httpCode = 503; } else if (is_string($finalAction) && strlen($finalAction) > 0) { wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => $finalAction, '503Time' => 3600))); $httpCode = 503; if ($isLockedOut) { parent::blockAction($e, $httpCode, $redirect, '503-lockout'); //exits } } } } else if (array_search('blocked', $failedRules) !== false) { parent::blockAction($e, $httpCode, $redirect, '403-blacklist'); //exits } parent::blockAction($e, $httpCode, $redirect, $template); } } /** * @param wfWAFBlockXSSException $e * @param int $httpCode */ public function blockXSSAction($e, $httpCode = 403, $redirect = false) { if ($this->isInLearningMode() && !$e->getRequest()->getMetadata('finalAction')) { register_shutdown_function(array( $this, 'whitelistFailedRulesIfNot404', )); $this->getStorageEngine()->logAttack($e->getFailedRules(), $e->getParamKey(), $e->getParamValue(), $e->getRequest()); $this->setLearningModeAttackException($e); } else { $failedRules = $e->getFailedRules(); if (empty($failedRules)) { $finalAction = $e->getRequest()->getMetadata('finalAction'); if (is_array($finalAction)) { $finalAction = $finalAction['action']; if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_REDIR) { $redirect = wfWAFIPBlocksController::currentController()->countryRedirURL(); } else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY_BYPASS_REDIR) { $redirect = wfWAFIPBlocksController::currentController()->countryBypassRedirURL(); } else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_UAREFIPRANGE) { wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Advanced blocking in effect.', '503Time' => 3600))); $httpCode = 503; } else if ($finalAction == wfWAFIPBlocksController::WFWAF_BLOCK_COUNTRY) { wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => 'Access from your area has been temporarily limited for security reasons.', '503Time' => 3600))); $httpCode = 503; } else if (is_string($finalAction) && strlen($finalAction) > 0) { wfWAF::getInstance()->getRequest()->setMetadata(array_merge(wfWAF::getInstance()->getRequest()->getMetadata(), array('503Reason' => $finalAction, '503Time' => 3600))); $httpCode = 503; } } } parent::blockXSSAction($e, $httpCode, $redirect); } } private function isCli() { return (php_sapi_name()==='cli') || !array_key_exists('REQUEST_METHOD', $_SERVER); } /** * */ public function runCron() { if($this->isCli()){ return; } /** * Removed sending attack data. Attack data is sent in @see wordfence::veryFirstAction */ $storage = $this->getStorageEngine(); $cron = (array) $storage->getConfig('cron', null, 'livewaf'); $run = array(); $updated = false; if (is_array($cron)) { /** @var wfWAFCronEvent $event */ $cronDeduplication = array(); foreach ($cron as $index => $event) { if (is_object($event) && $event instanceof wfWAFCronEvent) { $event->setWaf($this); if ($event->isInPast()) { $run[$index] = $event; $newEvent = $event->reschedule(); $className = is_object($newEvent) ? get_class($newEvent) : null; if ($newEvent && $newEvent instanceof wfWAFCronEvent && $newEvent !== $event && !in_array($className, $cronDeduplication)) { $cron[$index] = $newEvent; $cronDeduplication[] = $className; $updated = true; } else { unset($cron[$index]); $updated = true; } } else { $className = get_class($event); if (in_array($className, $cronDeduplication)) { unset($cron[$index]); $updated = true; } else { $cronDeduplication[] = $className; } } } else { //Remove bad/corrupt records unset($cron[$index]); $updated = true; } } } $storage->setConfig('cron', $cron, 'livewaf'); if ($updated && method_exists($storage, 'saveConfig')) { $storage->saveConfig('livewaf'); } foreach ($run as $index => $event) { $event->fire(); } } /** * */ public function whitelistFailedRulesIfNot404() { /** @var WP_Query $wp_query */ global $wp_query; if (defined('ABSPATH') && isset($wp_query) && class_exists('WP_Query') && $wp_query instanceof WP_Query && method_exists($wp_query, 'is_404') && $wp_query->is_404() && function_exists('is_admin') && !is_admin()) { return; } $this->whitelistFailedRules(); } /** * @param $ip * @return mixed */ public function isIPBlocked($ip) { return parent::isIPBlocked($ip); } /** * @param wfWAFRequest $request * @return bool|string false if it should not be blocked, otherwise true or a reason for blocking */ public function willPerformFinalAction($request) { try { $disableWAFIPBlocking = $this->getStorageEngine()->getConfig('disableWAFIPBlocking', null, 'synced'); $advancedBlockingEnabled = $this->getStorageEngine()->getConfig('advancedBlockingEnabled', null, 'synced'); } catch (Exception $e) { return false; } if ($disableWAFIPBlocking || !$advancedBlockingEnabled) { return false; } return wfWAFIPBlocksController::currentController()->shouldBlockRequest($request); } public function uninstall() { parent::uninstall(); @unlink(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess'); @unlink(rtrim(WFWAF_LOG_PATH, '/') . '/template.php'); @unlink(rtrim(WFWAF_LOG_PATH, '/') . '/GeoLite2-Country.mmdb'); self::_recursivelyRemoveWflogs(''); //Removes any remaining files and the directory itself } /** * Removes a path within wflogs, recursing as necessary. * * @param string $file * @param array $processedDirs * @return array The list of removed files/folders. */ private static function _recursivelyRemoveWflogs($file, $processedDirs = array()) { if (preg_match('~(?:^|/|\\\\)\.\.(?:/|\\\\|$)~', $file)) { return array(); } if (stripos(WFWAF_LOG_PATH, 'wflogs') === false) { //Sanity check -- if not in a wflogs folder, user will have to do removal manually return array(); } $path = rtrim(WFWAF_LOG_PATH, '/') . '/' . $file; if (is_link($path)) { if (@unlink($path)) { return array($file); } return array(); } if (is_dir($path)) { $real = realpath($file); if (in_array($real, $processedDirs)) { return array(); } $processedDirs[] = $real; $count = 0; $dir = opendir($path); if ($dir) { $contents = array(); while ($sub = readdir($dir)) { if ($sub == '.' || $sub == '..') { continue; } $contents[] = $sub; } closedir($dir); $filesRemoved = array(); foreach ($contents as $f) { $removed = self::_recursivelyRemoveWflogs($file . '/' . $f, $processedDirs); $filesRemoved = array($filesRemoved, $removed); } } if (@rmdir($path)) { $filesRemoved[] = $file; } return $filesRemoved; } if (@unlink($path)) { return array($file); } return array(); } public function fileList() { $fileList = parent::fileList(); $fileList[] = rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess'; $fileList[] = rtrim(WFWAF_LOG_PATH, '/') . '/template.php'; $fileList[] = rtrim(WFWAF_LOG_PATH, '/') . '/GeoLite2-Country.mmdb'; return $fileList; } /** * @return wfWAFRunException */ public function getLearningModeAttackException() { return $this->learningModeAttackException; } /** * @param wfWAFRunException $learningModeAttackException */ public function setLearningModeAttackException($learningModeAttackException) { $this->learningModeAttackException = $learningModeAttackException; } public static function permissions() { if (defined('WFWAF_LOG_FILE_MODE')) { return WFWAF_LOG_FILE_MODE; } if (class_exists('wfWAFStorageFile') && method_exists('wfWAFStorageFile', 'permissions')) { return wfWAFStorageFile::permissions(); } static $_cachedPermissions = null; if ($_cachedPermissions === null) { if (defined('WFWAF_LOG_PATH')) { $template = rtrim(WFWAF_LOG_PATH . '/') . '/template.php'; if (file_exists($template)) { $stat = @stat($template); if ($stat !== false) { $mode = $stat[2]; $updatedMode = 0600; if (($mode & 0020) == 0020) { $updatedMode = $updatedMode | 0060; } $_cachedPermissions = $updatedMode; return $updatedMode; } } } return 0660; } return $_cachedPermissions; } public static function writeHtaccess() { @file_put_contents(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', <<<APACHE <IfModule mod_authz_core.c> Require all denied </IfModule> <IfModule !mod_authz_core.c> Order deny,allow Deny from all </IfModule> APACHE ); @chmod(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', (wfWAFWordPress::permissions() | 0444)); } public function getGlobal($global) { if (wfWAFUtils::strpos($global, '.') === false) { return null; } list($prefix, $_global) = explode('.', $global); switch ($prefix) { case 'wordpress': if ($_global === 'core') { return $this->getStorageEngine()->getConfig('wordpressVersion', null, 'synced'); } else if ($_global === 'plugins') { return $this->getStorageEngine()->getConfig('wordpressPluginVersions', null, 'synced'); } else if ($_global === 'themes') { return $this->getStorageEngine()->getConfig('wordpressThemeVersions', null, 'synced'); } break; } return parent::getGlobal($global); } } class wfWAFWordPressStorageMySQL extends wfWAFStorageMySQL { public function getSerializedParams() { $params = parent::getSerializedParams(); $params[] = 'wordpressPluginVersions'; $params[] = 'wordpressThemeVersions'; return $params; } public function getAutoloadParams() { $params = parent::getAutoloadParams(); $params['synced'][] = 'wordpressVersion'; $params['synced'][] = 'wordpressPluginVersions'; $params['synced'][] = 'wordpressThemeVersions'; return $params; } } class wfWAFWordPressI18n implements wfWAFI18nEngine { protected $translations; /** @var wfWAFStorageInterface */ private $storageEngine; /** * @var wfMO */ private $mo; /** * @param wfWAFStorageInterface $storageEngine */ public function __construct($storageEngine) { $this->storageEngine = $storageEngine; $this->loadTranslations(); } /** * @param string $text * @return string */ public function __($text) { if (!$this->storageEngine->getConfig('wordfenceI18n', true, 'synced')) { return $text; } if ($this->mo) { $translated = $this->mo->translate($text); if ($translated) { return $translated; } } return $text; } protected function loadTranslations() { require_once dirname(__FILE__) . '/pomo/mo.php'; $currentLocale = $this->storageEngine->getConfig('WPLANG', '', 'synced'); // Find translation file for the current language. $mofile = dirname(__FILE__) . '/../languages/wordfence-' . $currentLocale . '.mo'; if (!file_exists($mofile)) { // No translation, use the default $mofile = dirname(__FILE__) . '/../languages/wordfence.mo'; } $this->mo = new wfMO(); return $this->mo->import_from_file( $mofile ); } } try { if (!defined('WFWAF_LOG_PATH')) { if (!defined('WP_CONTENT_DIR')) { //Loading before WordPress exit(); } define('WFWAF_LOG_PATH', WP_CONTENT_DIR . '/wflogs/'); } if (!is_dir(WFWAF_LOG_PATH)) { @mkdir(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755)); @chmod(WFWAF_LOG_PATH, (wfWAFWordPress::permissions() | 0755)); wfWAFWordPress::writeHtaccess(); } try { if (!defined('WFWAF_STORAGE_ENGINE') && isset($_SERVER['WFWAF_STORAGE_ENGINE'])) { define('WFWAF_STORAGE_ENGINE', $_SERVER['WFWAF_STORAGE_ENGINE']); } else if (!defined('WFWAF_STORAGE_ENGINE') && (WF_IS_WP_ENGINE || WF_IS_FLYWHEEL)) { define('WFWAF_STORAGE_ENGINE', 'mysqli'); } $specifiedStorageEngine = defined('WFWAF_STORAGE_ENGINE'); $fallbackStorageEngine = false; if ($specifiedStorageEngine) { switch (WFWAF_STORAGE_ENGINE) { case 'mysqli': $wfWAFDBCredentials = array(); $sslOptions = array(); $overrideConstants = array( 'wfWAFDBCredentials' => array( 'WFWAF_DB_NAME' => 'database', 'WFWAF_DB_USER' => 'user', 'WFWAF_DB_PASSWORD' => 'pass', 'WFWAF_DB_HOST' => 'host', 'WFWAF_DB_CHARSET' => 'charset', 'WFWAF_DB_COLLATE' => 'collation', 'WFWAF_MYSQL_CLIENT_FLAGS' => 'flags', 'WFWAF_TABLE_PREFIX' => 'tablePrefix' ), 'sslOptions' => array( 'WFWAF_DB_SSL_KEY' => 'key', 'WFWAF_DB_SSL_CERTIFICATE' => 'certificate', 'WFWAF_DB_SSL_CA_CERTIFICATE' => 'ca_certificate', 'WFWAF_DB_SSL_CA_PATH' => 'ca_path', 'WFWAF_DB_SSL_CIPHER_ALGOS' => 'cipher_algos' ) ); foreach ($overrideConstants as $variable => $constants) { foreach ($constants as $constant => $key) { if (defined($constant)) { ${$variable}[$key] = constant($constant); } } } // Find the wp-config.php if (is_dir(dirname(WFWAF_LOG_PATH))) { if (file_exists(dirname(WFWAF_LOG_PATH) . '/../wp-config.php')) { wfWAFUtils::extractCredentialsWPConfig(dirname(WFWAF_LOG_PATH) . '/../wp-config.php', $wfWAFDBCredentials); } else if (file_exists(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php')) { wfWAFUtils::extractCredentialsWPConfig(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php', $wfWAFDBCredentials); } } else if (!empty($_SERVER['DOCUMENT_ROOT'])) { if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php')) { wfWAFUtils::extractCredentialsWPConfig($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php', $wfWAFDBCredentials); } else if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/../wp-config.php')) { wfWAFUtils::extractCredentialsWPConfig($_SERVER['DOCUMENT_ROOT'] . '/../wp-config.php', $wfWAFDBCredentials); } } else { $wfWAFDBCredentials = false; } if (!empty($wfWAFDBCredentials)) { $wfWAFStorageEngine = new wfWAFWordPressStorageMySQL(new wfWAFStorageEngineMySQLi(), $wfWAFDBCredentials['tablePrefix'], wfShutdownRegistry::getDefaultInstance()); $wfWAFStorageEngine->getDb()->connect( $wfWAFDBCredentials['user'], $wfWAFDBCredentials['pass'], $wfWAFDBCredentials['database'], !empty($wfWAFDBCredentials['ipv6']) ? '[' . $wfWAFDBCredentials['host'] . ']' : $wfWAFDBCredentials['host'], !empty($wfWAFDBCredentials['port']) ? $wfWAFDBCredentials['port'] : null, !empty($wfWAFDBCredentials['socket']) ? $wfWAFDBCredentials['socket'] : null, array_key_exists('flags', $wfWAFDBCredentials) ? $wfWAFDBCredentials['flags'] : 0, $sslOptions ); if (array_key_exists('charset', $wfWAFDBCredentials)) { $wfWAFStorageEngine->getDb() ->setCharset($wfWAFDBCredentials['charset'], !empty($wfWAFDBCredentials['collation']) ? $wfWAFDBCredentials['collation'] : ''); } if (defined('ABSPATH')) { $tableExists = false; $optionName = 'wordfence_installed'; //Also exists in wfConfig.php if (is_multisite() && function_exists('get_network_option')) { $tableExists = get_network_option(null, $optionName, null); } else { $tableExists = get_option($optionName, null); } $wfWAFStorageEngine->installing = !$tableExists; $wfWAFStorageEngine->getDb()->installing = $wfWAFStorageEngine->installing; } } else { unset($wfWAFDBCredentials); } break; } } if (empty($wfWAFStorageEngine)) { $wfWAFStorageEngine = new wfWAFStorageFile( WFWAF_LOG_PATH . 'attack-data.php', WFWAF_LOG_PATH . 'ips.php', WFWAF_LOG_PATH . 'config.php', WFWAF_LOG_PATH . 'rules.php', WFWAF_LOG_PATH . 'wafRules.rules' ); if ($specifiedStorageEngine) $fallbackStorageEngine = true; } wfWAF::setSharedStorageEngine($wfWAFStorageEngine, $fallbackStorageEngine); wfWAF::setInstance(new wfWAFWordPress(wfWAFWordPressRequest::createFromGlobals(), wfWAF::getSharedStorageEngine())); wfWAF::getInstance()->getEventBus()->attach(new wfWAFWordPressObserver(wfWAF::getInstance())); if ($wfWAFStorageEngine instanceof wfWAFStorageFile) { $rulesFiles = array( WFWAF_LOG_PATH . 'rules.php', // WFWAF_PATH . 'rules.php', ); foreach ($rulesFiles as $rulesFile) { if (!file_exists($rulesFile) && !wfWAF::getInstance()->isReadOnly()) { @touch($rulesFile); } @chmod($rulesFile, (wfWAFWordPress::permissions() | 0444)); if (is_writable($rulesFile)) { wfWAF::getInstance()->setCompiledRulesFile($rulesFile); break; } } } else if ($wfWAFStorageEngine instanceof wfWAFStorageMySQL) { $wfWAFStorageEngine->runMigrations(); $wfWAFStorageEngine->setDefaults(); } if (!wfWAF::getInstance()->isReadOnly()) { if (wfWAF::getInstance()->getStorageEngine()->needsInitialRules()) { try { if (wfWAF::getInstance()->getStorageEngine()->getConfig('apiKey', null, 'synced') !== null && wfWAF::getInstance()->getStorageEngine()->getConfig('createInitialRulesDelay', null, 'transient') < time() ) { $event = new wfWAFCronFetchRulesEvent(time() - 60); $event->setWaf(wfWAF::getInstance()); $event->fire(); wfWAF::getInstance()->getStorageEngine()->setConfig('createInitialRulesDelay', time() + (5 * 60), 'transient'); } } catch (wfWAFBuildRulesException $e) { // Log this somewhere error_log($e->getMessage()); } catch (Exception $e) { // Suppress this error_log($e->getMessage()); } } } if (WFWAF_DEBUG && file_exists(wfWAF::getInstance()->getStorageEngine()->getRulesDSLCacheFile())) { try { wfWAF::getInstance()->updateRuleSet(file_get_contents(wfWAF::getInstance()->getStorageEngine()->getRulesDSLCacheFile()), false); } catch (wfWAFBuildRulesException $e) { $GLOBALS['wfWAFDebugBuildException'] = $e; } catch (Exception $e) { $GLOBALS['wfWAFDebugBuildException'] = $e; } } wfWAFI18n::setInstance(new wfWAFI18n(new wfWAFWordPressI18n($wfWAFStorageEngine))); try { wfWAF::getInstance()->run(); } catch (wfWAFBuildRulesException $e) { // Log this error_log($e->getMessage()); } } catch (wfWAFStorageFileConfigException $e) { // Let this request through for now error_log($e->getMessage()); } catch (wfWAFStorageEngineMySQLiException $e) { // Let this request through for now error_log($e->getMessage()); } catch (wfWAFStorageFileException $e) { // We need to choose another storage engine here. } } catch (Exception $e) { // In PHP 5, Throwable does not exist error_log("An unexpected exception occurred during WAF execution: {$e}"); $wf_waf_failure = array( 'throwable' => $e ); } catch (Throwable $t) { error_log("An unexpected exception occurred during WAF execution: {$t}"); if (class_exists('ParseError') && $t instanceof ParseError) { //Do nothing } else { $wf_waf_failure = array( 'throwable' => $t ); } } if (wfWAF::getInstance() === null) { require_once __DIR__ . '/dummy.php'; wfWAF::setInstance(new wfDummyWaf()); } define('WFWAF_RUN_COMPLETE', true); }PK �~\�Zײ � waf-uninstall-success.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the success message for WAF auto prepend uninstallation. * * Expects $active and $subdirectory. * * @var bool $active True if the WAF's auto_prepend_file is active and not because of a subdirectory install. * @var bool $subdirectory True if the WAF's auto_prepend_file is active because of a subdirectory install. */ if (!$active && !$subdirectory): ?> <p><?php esc_html_e('Uninstallation was successful!', 'wordfence'); ?></p> <?php elseif (!$active): ?> <p><?php esc_html_e('Uninstallation from this site was successful! The Wordfence Firewall is still active because it is installed in another WordPress installation.', 'wordfence'); ?></p> <?php else: ?> <p><?php esc_html_e('The changes have not yet taken effect. If you are using LiteSpeed or IIS as your web server or CGI/FastCGI interface, you may need to wait a few minutes for the changes to take effect since the configuration files are sometimes cached. You also may need to select a different server configuration in order to complete this step, but wait for a few minutes before trying. You can try refreshing this page.', 'wordfence'); ?></p> <?php endif; ?> PK �~\ [��� � waf-modal-wrapper.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the content given in a modal wrapper for the WAF install/uninstall flow. * * Expects $title and $html to be defined. $helpHTML, $footerHTML, and $footerButtonTitle may also be defined. * * @var string $title The title for the panel. * @var string $html The main HTML content for the panel. * @var string $helpHTML HTML content for the help area next to the close button. * @var string $footerHTML HTML content for the footer area next to the footer button. * @var string $footerButtonTitle Title for the footer button, defaults to "Continue". * @var bool $noX Optional, hides the top right x button if truthy. */ if (!isset($footerButtonTitle)) { $footerButtonTitle = __('Continue', 'wordfence'); } $showX = !isset($noX) || !$noX; ?> <div class="wf-modal"> <div class="wf-modal-header"> <div class="wf-modal-header-content"> <div class="wf-modal-title"> <strong><?php echo $title; ?></strong> </div> </div> <div class="wf-modal-header-action"> <div><?php if (isset($helpHTML)) { echo $helpHTML; } ?></div> <?php if ($showX) { ?><div class="wf-padding-add-left-small wf-modal-header-action-close"><a href="#" onclick="WFAD.colorboxClose(); return false" role="button"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div><?php } ?> </div> </div> <div class="wf-modal-content"> <?php echo $html; ?> </div> <div class="wf-modal-footer"> <ul class="wf-flex-horizontal wf-flex-full-width"> <li><?php if (isset($footerHTML)) { echo $footerHTML; } ?></li> <li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle" id="wf-waf-modal-continue" role="button"><?php echo esc_html($footerButtonTitle); ?></a></li> </ul> </div> </div>PK �~\�QQ/ Q/ options-group-whitelisted.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the Whitelisted URLs group. * * Expects $firewall, $waf, and $stateKey. * * @var wfFirewall $firewall * @var wfWAF $waf * @var string $stateKey The key under which the collapse state is stored. * @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true. */ $config = $waf->getStorageEngine(); if (!isset($collapseable)) { $collapseable = true; } ?> <div class="wf-row"> <div class="wf-col-xs-12"> <div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>"> <div class="wf-block-header"> <div class="wf-block-header-content"> <div class="wf-block-title"> <strong><?php esc_html_e('Allowlisted URLs', 'wordfence'); ?></strong> </div> <?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?> </div> </div> <div class="wf-block-content"> <ul class="wf-block-list"> <?php if ($firewall->isSubDirectoryInstallation()): ?> <li> <p><?php echo wp_kses(sprintf(__('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please <a href="%s">click here</a> to configure the Firewall to run correctly on this site.', 'wordfence'), esc_attr(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#configureAutoPrepend'))), array('a'=>array('href'=>array()))); ?></p> </li> <?php else: ?> <li> <?php echo wfView::create('waf/option-whitelist', array( ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled-multiple', array( 'options' => array( array( 'name' => 'ajaxWatcherDisabled_front', 'enabledValue' => 0, 'disabledValue' => 1, 'value' => wfConfig::get('ajaxWatcherDisabled_front') ? 1 : 0, 'title' => __('Front-end Website', 'wordfence'), ), array( 'name' => 'ajaxWatcherDisabled_admin', 'enabledValue' => 0, 'disabledValue' => 1, 'value' => wfConfig::get('ajaxWatcherDisabled_admin') ? 1 : 0, 'title' => __('Admin Panel', 'wordfence'), ), ), 'noSpacer' => true, 'htmlTitle' => '<strong>' . esc_html__('Monitor background requests from an administrator\'s web browser for false positives', 'wordfence') . '</strong>', 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_MONITOR_AJAX), ))->render(); ?> </li> <?php endif; ?> </ul> </div> </div> </div> </div> <!-- end whitelisted urls --> <script type="text/x-jquery-template" id="waf-whitelisted-urls-tmpl"> <div class="whitelist-table-container"> <table class="wf-striped-table whitelist-table"> <thead> <tr> <th style="width: 2%;text-align: center"><div class="wf-whitelist-bulk-select wf-option-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-label="<?php esc_attr_e('Select/deselect all', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></th> <th style="width: 5%;"><?php esc_html_e('Enabled', 'wordfence'); ?></th> <th><?php esc_html_e('URL', 'wordfence'); ?></th> <th><?php esc_html_e('Param', 'wordfence'); ?></th> <th><?php esc_html_e('Created', 'wordfence'); ?></th> <th><?php esc_html_e('Source', 'wordfence'); ?></th> <th><?php esc_html_e('User', 'wordfence'); ?></th> <th><?php esc_html_e('IP', 'wordfence'); ?></th> </tr> </thead> {{if whitelistedURLParams.length > 5}} <tfoot> <tr> <th style="width: 2%;text-align: center"><div class="wf-whitelist-bulk-select wf-option-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-label="<?php esc_attr_e('Select/deselect all', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></th> <th style="width: 5%;"><?php esc_html_e('Enabled', 'wordfence'); ?></th> <th><?php esc_html_e('URL', 'wordfence'); ?></th> <th><?php esc_html_e('Param', 'wordfence'); ?></th> <th><?php esc_html_e('Created', 'wordfence'); ?></th> <th><?php esc_html_e('Source', 'wordfence'); ?></th> <th><?php esc_html_e('User', 'wordfence'); ?></th> <th><?php esc_html_e('IP', 'wordfence'); ?></th> </tr> {{/if}} </tfoot> <tbody> {{each(idx, whitelistedURLParam) whitelistedURLParams}} <tr data-index="${idx}" data-adding="{{if (whitelistedURLParam.adding)}}1{{else}}0{{/if}}" data-key="${whitelistedURLParam.path}|${whitelistedURLParam.paramKey}"> <td style="text-align: center;"><div class="wf-whitelist-table-bulk-checkbox wf-option-checkbox" role="checkbox" aria-checked="false" tabindex="0" aria-label="<?php esc_attr_e('Select row ${idx}', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></td> <td style="text-align: center;"><div class="wf-whitelist-item-enabled wf-option-checkbox{{if (!whitelistedURLParam.data.disabled)}} wf-checked{{/if}}" data-original-value="{{if (!whitelistedURLParam.data.disabled)}}1{{else}}0{{/if}}" role="checkbox" aria-checked="{{if (!whitelistedURLParam.data.disabled)}}true{{else}}false{{/if}}" tabindex="0" aria-label="<?php esc_attr_e('Toggle row ${idx}', 'wordfence'); ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div></td> <td data-column="url"> <input name="replaceWhitelistedPath" type="hidden" value="${whitelistedURLParam.path}"> <span class="whitelist-display">${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.path))}</span> <input name="whitelistedPath" class="whitelist-edit whitelist-path" type="text" value="${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.path))}"> </td> <td data-column="param"> <input name="replaceWhitelistedParam" type="hidden" value="${whitelistedURLParam.paramKey}"> <span class="whitelist-display">${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.paramKey))}</span> <input name="whitelistedParam" class="whitelist-edit whitelist-param-key" type="text" value="${WFAD.htmlEscape(WFAD.base64_decode(whitelistedURLParam.paramKey))}"> </td> <td> {{if (whitelistedURLParam.data.timestamp)}} ${WFAD.dateFormat((new Date(whitelistedURLParam.data.timestamp * 1000)))} {{else}} - {{/if}} </td> <td data-column="source"> {{if (whitelistedURLParam.data.description)}} ${whitelistedURLParam.data.description} {{else}} - {{/if}} </td> <td data-column="user"> {{if (whitelistedURLParam.data.userID)}} {{if (whitelistedURLParam.data.username)}} ${whitelistedURLParam.data.username} {{else}} ${whitelistedURLParam.data.userID} {{/if}} {{else}} - {{/if}} </td> <td data-column="ip"> {{if (whitelistedURLParam.data.ip)}} ${whitelistedURLParam.data.ip} {{else}} - {{/if}} </td> </tr> {{/each}} {{if (whitelistedURLParams.length == 0)}} <tr> <td colspan="8"><?php esc_html_e('No allowlisted URLs currently set.', 'wordfence'); ?></td> </tr> {{/if}} </tbody> </table> </div> </script> <script type="application/javascript"> (function($) { function whitelistCheckAllVisible() { $('.wf-whitelist-bulk-select.wf-option-checkbox').toggleClass('wf-checked', true).attr('aria-checked', 'true'); $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox').each(function() { $(this).toggleClass('wf-checked', $(this).closest('tr').is(':visible')).attr('aria-checked', $(this).closest('tr').is(':visible') ? 'true' : 'false'); }); } function whitelistUncheckAll() { $('.wf-whitelist-bulk-select.wf-option-checkbox').toggleClass('wf-checked', false).attr('aria-checked', 'false'); $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox').toggleClass('wf-checked', false).attr('aria-checked', 'false'); } $(window).on('wordfenceWAFInstallWhitelistEventHandlers', function() { //Enabled/Disabled $('.wf-whitelist-item-enabled.wf-option-checkbox').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); var row = $(this).closest('tr'); var key = row.data('key'); var value = $(this).hasClass('wf-checked') ? 1 : 0; if (value) { $(this).removeClass('wf-checked').attr('aria-checked', 'false'); value = 0; } else { $(this).addClass('wf-checked').attr('aria-checked', 'true'); value = 1; } WFAD.wafWhitelistedChangeEnabled(key, value); WFAD.updatePendingChanges(); }); }); //Header/Footer Bulk Action $('.wf-whitelist-bulk-select.wf-option-checkbox').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); if ($(this).hasClass('wf-checked')) { $(this).removeClass('wf-checked').attr('aria-checked', 'false'); whitelistUncheckAll(); } else { $(this).addClass('wf-checked'); whitelistCheckAllVisible().attr('aria-checked', 'true'); } }); }); //Row Bulk Action $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); var row = $(this).closest('tr'); var key = row.data('key'); var value = $(this).hasClass('wf-checked') ? 1 : 0; if (value) { $(this).removeClass('wf-checked').attr('aria-checked', 'false'); } else { $(this).addClass('wf-checked').attr('aria-checked', 'true'); } var totalCount = $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox:visible').length; var checkedCount = $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox.wf-checked:visible').length; if (totalCount == 0 || (checkedCount != totalCount)) { $('.wf-whitelist-bulk-select.wf-option-checkbox').removeClass('wf-checked').attr('aria-checked', 'false'); } else { $('.wf-whitelist-bulk-select.wf-option-checkbox').addClass('wf-checked').attr('aria-checked', 'true'); } }); }); $(window).trigger('wordfenceWAFApplyWhitelistFilter'); }); $(window).on('wordfenceWAFApplyWhitelistFilter', function() { if (WFAD.wafData.whitelistedURLParams.length == 0) { return; } var filterColumn = $('#whitelist-table-controls select').val(); var filterValue = $('input[name="filterValue"]').val(); if (typeof filterValue != 'string' || filterValue.length == 0) { $('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-index]').show(); } else { $('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-index]').each(function() { var text = $(this).find('td[data-column="' + filterColumn + '"]').text(); if (text.indexOf(filterValue) > -1) { $(this).show(); } else { $(this).hide(); } }); } }); $(window).on('wordfenceWAFConfigPageRender', function() { //Add event handler to whitelist checkboxes $(window).trigger('wordfenceWAFInstallWhitelistEventHandlers'); }); })(jQuery); </script>PK �~\}:��O O waf-install-success.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the success message for WAF auto prepend installation. * * Expects $active. * * @var bool $active True if the WAF's auto_prepend_file is active and not because of a subdirectory install. */ if ($active): ?> <p><?php esc_html_e('Nice work! The firewall is now optimized.', 'wordfence'); ?></p> <?php else: ?> <p><?php esc_html_e('The changes have not yet taken effect. If you are using LiteSpeed or IIS as your web server or CGI/FastCGI interface, you may need to wait a few minutes for the changes to take effect since the configuration files are sometimes cached. You also may need to select a different server configuration in order to complete this step, but wait for a few minutes before trying. You can try refreshing this page.', 'wordfence'); ?></p> <?php endif; ?> PK �~\��� � option-whitelist.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?> <ul id="wf-option-wafWhitelist" class="wf-option wf-flex-vertical wf-flex-full-width"> <li><strong><?php esc_html_e('Add Allowlisted URL/Param', 'wordfence'); ?></strong> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_WHITELIST); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a> <?php esc_html_e('The URL/parameters in this table will not be tested by the firewall. They are typically added while the firewall is in Learning Mode or by an admin who identifies a particular action/request is a false positive.', 'wordfence'); ?></li> <li id="whitelist-form"> <div class="wf-form-inline"> <div class="wf-form-group"> <input class="wf-form-control" type="text" name="whitelistURL" id="whitelistURL" placeholder="<?php esc_attr_e('URL', 'wordfence'); ?>"> </div> <div class="wf-form-group"> <select class="wf-form-control" name="whitelistParam" id="whitelistParam"> <option value="request.body"><?php esc_html_e('POST Body', 'wordfence'); ?></option> <option value="request.cookies"><?php esc_html_e('Cookie', 'wordfence'); ?></option> <option value="request.fileNames"><?php esc_html_e('File Name', 'wordfence'); ?></option> <option value="request.headers"><?php esc_html_e('Header', 'wordfence'); ?></option> <option value="request.queryString"><?php esc_html_e('Query String', 'wordfence'); ?></option> </select> </div> <div class="wf-form-group"> <input class="wf-form-control" type="text" name="whitelistParamName" id="whitelistParamName" placeholder="<?php esc_attr_e('Param Name', 'wordfence'); ?>"> </div> <a href="#" class="wf-btn wf-btn-callout wf-btn-primary wf-disabled" id="waf-whitelisted-urls-add" role="button"><?php esc_html_e('Add', 'wordfence'); ?></a> </div> <script type="application/javascript"> (function($) { $(function() { $('#whitelistURL, #whitelistParamName').on('change paste keyup', function() { setTimeout(function() { $('#waf-whitelisted-urls-add').toggleClass('wf-disabled', $('#whitelistURL').val().length == 0 || $('#whitelistParamName').val().length == 0); }, 100); }); $('#waf-whitelisted-urls-add').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var form = $('#whitelist-form'); var inputURL = form.find('[name=whitelistURL]'); var inputParam = form.find('[name=whitelistParam]'); var inputParamName = form.find('[name=whitelistParamName]'); var url = inputURL.val(); var param = inputParam.val(); var paramName = inputParamName.val(); if (url && param) { <?php $user = wp_get_current_user(); ?> var paramKey = WFAD.base64_encode(param + '[' + paramName + ']'); var pathKey = WFAD.base64_encode(url); var key = pathKey + '|' + paramKey; var matches = $('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-key="' + key + '"]'); if (matches.length > 0) { WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), '<?php esc_attr_e('Allowlist Entry Exists', 'wordfence'); ?>', '<?php esc_attr_e('An allowlist entry for this URL and parameter already exists.', 'wordfence'); ?>'); return; } //Generate entry and add to display data set var entry = { data: { description: "<?php esc_attr_e('Allowlisted via Firewall Options page', 'wordfence'); ?>", source: 'waf-options', disabled: false, ip: "<?php echo esc_attr(wfUtils::getIP()); ?>", timestamp: Math.round(Date.now() / 1000), userID: <?php echo (int) $user->ID; ?>, username: "<?php echo esc_attr($user->user_login); ?>" }, paramKey: paramKey, path: pathKey, ruleID: ['all'], adding: true }; WFAD.wafData.whitelistedURLParams.push(entry); //Add to change list if (!(WFAD.pendingChanges['whitelistedURLParams'] instanceof Object)) { WFAD.pendingChanges['whitelistedURLParams'] = {}; } if (!(WFAD.pendingChanges['whitelistedURLParams']['add'] instanceof Object)) { WFAD.pendingChanges['whitelistedURLParams']['add'] = {}; } WFAD.pendingChanges['whitelistedURLParams']['add'][key] = entry; WFAD.updatePendingChanges(); //Reload and reset add form var whitelistedIPsEl = $('#waf-whitelisted-urls-tmpl').tmpl(WFAD.wafData); $('#waf-whitelisted-urls-wrapper').html(whitelistedIPsEl); $(window).trigger('wordfenceWAFInstallWhitelistEventHandlers'); inputURL.val(''); inputParamName.val(''); } }); }); })(jQuery); </script> </li> <li><hr id="whitelist-form-separator"></li> <li id="whitelist-table-controls" class="wf-flex-horizontal wf-flex-vertical-xs wf-flex-full-width"> <div><a href="#" id="whitelist-bulk-delete" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Delete', 'wordfence'); ?></a> <a href="#" id="whitelist-bulk-enable" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Enable', 'wordfence'); ?></a> <a href="#" id="whitelist-bulk-disable" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Disable', 'wordfence'); ?></a></div> <div class="wf-right wf-left-xs wf-padding-add-top-xs-small"> <div class="wf-select-group wf-flex-vertical-xs wf-flex-full-width"> <select name="filterColumn"> <option value="url"><?php esc_html_e('URL', 'wordfence'); ?></option> <option value="param"><?php esc_html_e('Param', 'wordfence'); ?></option> <option value="source"><?php esc_html_e('Source', 'wordfence'); ?></option> <option value="user"><?php esc_html_e('User', 'wordfence'); ?></option> <option value="ip"><?php esc_html_e('IP', 'wordfence'); ?></option> </select> <input type="text" class="wf-form-control" placeholder="<?php esc_attr_e('Filter Value', 'wordfence'); ?>" name="filterValue"> <div><span class="wf-hidden-xs"> </span><a href="#" id="whitelist-apply-filter" class="wf-btn wf-btn-callout wf-btn-default" role="button"><?php esc_html_e('Filter', 'wordfence'); ?></a></div> </div> <script type="application/javascript"> (function($) { $(function() { $('#whitelist-apply-filter').on('click', function(e) { e.preventDefault(); e.stopPropagation(); $(window).trigger('wordfenceWAFApplyWhitelistFilter'); }); }); })(jQuery); </script> </div> </li> <li> <div id="waf-whitelisted-urls-wrapper"></div> </li> </ul> <script type="application/javascript"> (function($) { $(function() { $('#whitelistParam').wfselect2({ minimumResultsForSearch: -1, templateSelection: function(item) { return 'Param Type: ' + item.text; } }); $('#whitelist-table-controls select').wfselect2({ minimumResultsForSearch: -1, placeholder: "Filter By", width: '200px', templateSelection: function(item) { return 'Filter By: ' + item.text; } }); $('#whitelist-bulk-delete').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.wafWhitelistedBulkDelete(); WFAD.updatePendingChanges(); var whitelistedIPsEl = $('#waf-whitelisted-urls-tmpl').tmpl(WFAD.wafData); $('#waf-whitelisted-urls-wrapper').html(whitelistedIPsEl); $(window).trigger('wordfenceWAFInstallWhitelistEventHandlers'); }); $('#whitelist-bulk-enable').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.wafWhitelistedBulkChangeEnabled(true); WFAD.updatePendingChanges(); }); $('#whitelist-bulk-disable').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.wafWhitelistedBulkChangeEnabled(false); WFAD.updatePendingChanges(); }); }); })(jQuery); </script> PK �~\��ߘX( X( # options-group-advanced-firewall.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the Advanced Firewall Options group. * * Expects $firewall, $waf, and $stateKey. * * @var wfFirewall $firewall * @var wfWAF $waf * @var string $stateKey The key under which the collapse state is stored. * @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true. */ $config = $waf->getStorageEngine(); if (!isset($collapseable)) { $collapseable = true; } ?> <div class="wf-row"> <div class="wf-col-xs-12"> <div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>"> <div class="wf-block-header"> <div class="wf-block-header-content"> <div class="wf-block-title"> <strong><?php esc_html_e('Advanced Firewall Options', 'wordfence'); ?></strong> </div> <?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?> </div> </div> <div class="wf-block-content"> <ul class="wf-block-list"> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'disableWAFIPBlocking', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('disableWAFIPBlocking') ? 1 : 0, 'title' => __('Delay IP and Country blocking until after WordPress and plugins have loaded (only process firewall rules early)', 'wordfence'), 'subtitle' => ($firewall->isSubDirectoryInstallation() ? __('You are currently running the WAF from another WordPress installation. This option can be changed once you configure the firewall to run correctly on this site.', 'wordfence') : ''), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_DELAY_BLOCKING), 'disabled' => $firewall->isSubDirectoryInstallation(), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-textarea', array( 'textOptionName' => 'whitelisted', 'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('whitelisted')), 'title' => __('Allowlisted IP addresses that bypass all rules', 'wordfence'), 'alignTitle' => 'top', 'subtitleHTML' => wp_kses(__('Allowlisted IPs must be separated by commas or placed on separate lines. You can specify ranges using the following formats: 127.0.0.1/24, 127.0.0.[1-100], or 127.0.0.1-127.0.1.100<br/>Wordfence automatically allowlists <a href="http://en.wikipedia.org/wiki/Private_network" target="_blank" rel="noopener noreferrer">private networks<span class="screen-reader-text"> (opens in new tab)</span></a> because these are not routable on the public Internet.', 'wordfence'), array('br'=>array(), 'a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))), 'subtitlePosition' => 'value', 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_WHITELISTED_IPS), ))->render(); ?> </li> <li> <?php $whitelistedServices = wfConfig::getJSON('whitelistedServices', array()); $whitelistPresets = wfUtils::whitelistPresets(); $names = array(); foreach ($whitelistPresets as $tag => $preset) { if (!isset($preset['n'])) { continue; } //Not named, omitted from configurable list if ((isset($preset['h']) && $preset['h']) || (isset($preset['f']) && $preset['f'])) { continue; } //Flagged as hidden or always enabled, omitted from configurable list $names[$tag] = $preset['n']; if (!isset($whitelistedServices[$tag]) && isset($preset['d']) && $preset['d']) { $whitelistedServices[$tag] = 1; } } $options = array(); foreach ($names as $tag => $name) { $options[] = array( 'name' => 'whitelistedServices.' . preg_replace('/[^a-z0-9]/i', '', $tag), 'enabledValue' => 1, 'disabledValue' => 0, 'value' => (isset($whitelistedServices[$tag]) && $whitelistedServices[$tag]) ? 1 : 0, 'title' => $name, ); } echo wfView::create('options/option-toggled-multiple', array( 'options' => $options, 'title' => __('Allowlisted services', 'wordfence'), 'id' => 'wf-option-whitelistedServices', 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_WHITELISTED_SERVICES), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-textarea', array( 'textOptionName' => 'bannedURLs', 'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('bannedURLs')), 'title' => __('Immediately block IPs that access these URLs', 'wordfence'), 'alignTitle' => 'top', 'subtitle' => __('Separate multiple URLs with commas or place them on separate lines. Asterisks are wildcards, but use with care. If you see an attacker repeatedly probing your site for a known vulnerability you can use this to immediately block them. All URLs must start with a "/" without quotes and must be relative. e.g. /badURLone/, /bannedPage.html, /dont-access/this/URL/, /starts/with-*', 'wordfence'), 'subtitlePosition' => 'value', 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_IMMEDIATELY_BLOCK_URLS), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-textarea', array( 'textOptionName' => 'wafAlertWhitelist', 'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('wafAlertWhitelist')), 'title' => __('Ignored IP addresses for Wordfence Web Application Firewall alerting', 'wordfence'), 'alignTitle' => 'top', 'subtitle' => __('Ignored IPs must be separated by commas or placed on separate lines. These addresses will be ignored from any alerts about increased attacks and can be used to ignore things like standalone website security scanners.', 'wordfence'), 'subtitlePosition' => 'value', 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_IGNORED_ALERT_IPS), ))->render(); ?> </li> <li> <?php echo wfView::create('waf/option-rules', array( 'firewall' => $firewall, ))->render(); ?> </li> </ul> </div> </div> </div> </div> <!-- end advanced firewall options --> <script type="text/x-jquery-template" id="waf-rules-tmpl"> <table class="wf-striped-table"> <thead> <tr> <th style="width: 5%"></th> <th><?php esc_html_e('Category', 'wordfence'); ?></th> <th><?php esc_html_e('Description', 'wordfence'); ?></th> </tr> </thead> <tbody> {{each(idx, rule) rules}} <tr data-rule-id="${rule.ruleID}" data-original-value="{{if (!disabledRules[rule.ruleID])}}1{{else}}0{{/if}}"> <td style="text-align: center"> <div class="wf-rule-toggle wf-boolean-switch{{if (!disabledRules[rule.ruleID])}} wf-active{{/if}}<?php echo ($firewall->isSubDirectoryInstallation() ? ' wf-disabled' : ''); ?>"><a href="#" class="wf-boolean-switch-handle"></a></div> </td> <td>${rule.category}</td> <td>${rule.description}</td> </tr> {{/each}} {{if (rules.length == 0)}} <tr> <td colspan="4"><?php esc_html_e('No rules currently set.', 'wordfence'); ?> <?php if (!($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_EXTENDED && $firewall->isSubDirectoryInstallation())) { echo wp_kses(__('<a href="#" onclick="WFAD.wafUpdateRules();return false;" role="button">Click here</a> to pull down the latest from the Wordfence servers.', 'wordfence'), array('a'=>array('href'=>array(), 'onclick'=>array(), 'role'=>array()))); } ?> </td> </tr> {{/if}} </tbody> <tfoot> {{if (ruleCount >= 10)}} <tr id="waf-show-all-rules"> <td class="wf-center" colspan="4"><a href="#" id="waf-show-all-rules-button" role="button"><?php esc_html_e('SHOW ALL RULES', 'wordfence'); ?></a></td> </tr> {{/if}} </tfoot> </table> </script> <script type="application/javascript"> (function($) { $(window).on('wordfenceWAFConfigPageRender', function() { delete WFAD.pendingChanges['wafRules']; //Add event handler to rule checkboxes $('.wf-rule-toggle.wf-boolean-switch').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).find('.wf-boolean-switch-handle').trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); $(this).find('.wf-boolean-switch-handle').trigger('click'); }); $(this).find('.wf-boolean-switch-handle').on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).find('.wf-boolean-switch-handle').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var control = $(this).closest('.wf-boolean-switch'); var row = $(this).closest('tr'); var ruleID = row.data('ruleId'); var value = control.hasClass('wf-active') ? 1 : 0; if (value) { control.removeClass('wf-active').attr('aria-checked', 'false'); value = 0; } else { control.addClass('wf-active').attr('aria-checked', 'false'); value = 1; } var originalValue = row.data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges['wafRules'][ruleID]; if (Object.keys(WFAD.pendingChanges['wafRules']).length == 0) { delete WFAD.pendingChanges['wafRules'] } } else { if (!(WFAD.pendingChanges['wafRules'] instanceof Object)) { WFAD.pendingChanges['wafRules'] = {}; } WFAD.pendingChanges['wafRules'][ruleID] = value; } $(control).trigger('change', [false]); WFAD.updatePendingChanges(); }); }); }); })(jQuery); </script>PK �~\�k� � status-tooltip-learning-mode.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?> <ul class="wf-flex-horizontal wf-flex-full-width wf-no-top"> <li class="wf-tip-light-bulb"><i class="wf-ion-ios-lightbulb-outline"></i></li> <li class="wf-tip-info-message"><strong><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('The Web Application Firewall is currently in Learning Mode. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_LEARNING_MODE)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></strong></li> </ul>PK �~\8�w�� � debug.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** @var wfRequestModel $hit */ /** @var stdClass $hitData */ $title = sprintf('Debugging #%d as False Positive', $hit->id); $fields = array( 'URL' => $hit->URL, 'Timestamp' => date('r', $hit->ctime), 'IP' => wfUtils::inet_ntop($hit->IP), 'Status Code' => $hit->statusCode, 'User Agent' => $hit->UA, 'Referer' => $hit->referer, ); if (isset($hitData->fullRequest)) { $requestString = base64_decode($hitData->fullRequest); $request = wfWAFRequest::parseString($requestString); } else { $request = new wfWAFRequest(); $request->setAuth(array()); $request->setBody(array()); $request->setCookies(array()); $request->setFileNames(array()); $request->setFiles(array()); $request->setHeaders(array()); $request->setHost(''); $request->setIp(''); $request->setMethod('GET'); $request->setPath(''); $request->setProtocol('http'); $request->setQueryString(array()); $request->setTimestamp(''); $request->setUri(''); $headers = array(); $urlPieces = parse_url($hit->URL); if ($urlPieces) { if (array_key_exists('scheme', $urlPieces)) { $request->setProtocol($urlPieces['scheme']); } if (array_key_exists('host', $urlPieces)) { $request->setHost($urlPieces['host']); $headers['Host'] = $urlPieces['host']; } $uri = '/'; if (array_key_exists('path', $urlPieces)) { $request->setPath($urlPieces['path']); $uri = $urlPieces['path']; } if (array_key_exists('query', $urlPieces)) { $uri .= '?' . $urlPieces['query']; parse_str($urlPieces['query'], $query); $request->setQueryString($query); } $request->setUri($uri); } $headers['User-Agent'] = $hit->UA; $headers['Referer'] = $hit->referer; $request->setHeaders($headers); preg_match('/request\.([a-z]+)(?:\[(.*?)\](.*?))?/i', $hitData->paramKey, $matches); if ($matches) { switch ($matches[1]) { case 'body': $request->setMethod('POST'); parse_str("$matches[2]$matches[3]", $body); $request->setBody($body); break; } } } $request->setIP(wfUtils::inet_ntop($hit->IP)); $request->setTimestamp($hit->ctime); $waf = wfWAF::getInstance(); $waf->setRequest($request); $result = '<strong class="ok">Passed</strong>'; $failedRules = array(); try { $waf->runRules(); } catch (wfWAFAllowException $e) { $result = '<strong class="ok">Allowlisted</strong>'; } catch (wfWAFBlockException $e) { $result = '<strong class="error">Blocked</strong>'; $failedRules = $waf->getFailedRules(); } catch (wfWAFBlockSQLiException $e) { $result = '<strong class="error">Blocked For SQLi</strong>'; $failedRules = $waf->getFailedRules(); } catch (wfWAFBlockXSSException $e) { $result = '<strong class="error">Blocked For XSS</strong>'; $failedRules = $waf->getFailedRules(); } ?> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title><?php echo esc_html($title) ?></title> <link rel="stylesheet" href="<?php echo wfUtils::getBaseURL() . wfUtils::versionedAsset('css/main.css'); ?>"> <link rel="stylesheet" href="<?php echo wfLicense::current()->getStylesheet(); ?>"> <style> html { font-family: "Open Sans", Helvetica, Arial, sans-serif; } h1, h2, h3, h4, h5 { margin: 20px 0px 8px; } pre, p { margin: 8px 0px 20px; } pre.request-debug { padding: 12px; background: #fafafa; border: 1px solid #999999; overflow: auto; } pre.request-debug em { font-style: normal; padding: 1px; border: 1px solid #ffb463; background-color: #ffffe0; border-radius: 2px; } pre.request-debug strong { border: 1px solid #ff4a35; background-color: #ffefe7; margin: 1px; } .ok { color: #00c000; } .error { color: #ff4a35; } #wrapper { max-width: 1060px; margin: 0px auto; } </style> </head> <body> <div id="wrapper"> <h1><?php echo esc_html($title) ?></h1> <table class="wf-striped-table"> <thead> <tr> <th colspan="2">Request Details</th> </tr> </thead> <?php foreach ($fields as $label => $value): ?> <tr> <td><?php echo esc_html($label) ?>:</td> <td><?php echo esc_html($value) ?></td> </tr> <?php endforeach ?> </table> <h4>HTTP Request: <?php echo $result ?></h4> <?php if (!isset($hitData->fullRequest)): ?> <em style="font-size: 14px;">This is a reconstruction of the request using what was flagged by the WAF. Full requests are only stored when <code>WFWAF_DEBUG</code> is enabled.</em> <?php endif ?> <pre class="request-debug"><?php $paramKey = wp_hash(uniqid('param', true)); $matchKey = wp_hash(uniqid('match', true)); $template = array( "[$paramKey]" => '<em>', "[/$paramKey]" => '</em>', "[$matchKey]" => '<strong>', "[/$matchKey]" => '</strong>', ); $highlightParamFormat = "[$paramKey]%s[/$paramKey]"; $highlightMatchFormat = "[$matchKey]%s[/$matchKey]"; $requestOut = esc_html($request->highlightFailedParams($failedRules, $highlightParamFormat, $highlightMatchFormat)); echo str_replace(array_keys($template), $template, $requestOut) ?></pre> <?php if ($failedRules): ?> <h4>Failed Rules</h4> <table class="wf-striped-table"> <thead> <tr> <th>ID</th> <th>Category</th> </tr> </thead> <tbody> <?php foreach ($failedRules as $paramKey => $categories) { foreach ($categories as $categoryKey => $failed) { foreach ($failed as $failedRule) { /** @var wfWAFRule $rule */ $rule = $failedRule['rule']; printf("<tr><td>%d</td><td>%s</td></tr>", $rule->getRuleID(), $rule->getDescription()); } } } ?> </tbody> </table> <?php endif ?> <p> <button type="button" id="run-waf-rules">Run Through WAF Rules</button> </p> <script> document.getElementById('run-waf-rules').onclick = function() { document.location.href = document.location.href; } </script> </div> </body> </html>PK �~\/7Íu u option-rules.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?> <ul id="wf-option-wafRules" class="wf-option wf-flex-vertical wf-flex-align-left"> <li class="wf-option-title"><strong><?php esc_html_e('Rules', 'wordfence'); ?></strong> <a href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_RULES); ?>" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></li> <li class="wf-option-subtitle"><?php echo ($firewall->isSubDirectoryInstallation() ? esc_html__('You are currently running the WAF from another WordPress installation. These rules can be disabled or enabled once you configure the firewall to run correctly on this site.', 'wordfence') : ''); ?></li> <li id="waf-rules-wrapper" class="wf-add-top"></li> <?php if (!WFWAF_SUBDIRECTORY_INSTALL): ?> <li id="waf-rules-manual-update"> <ul class="wf-option wf-option-footer wf-padding-no-bottom"> <li><a class="wf-btn wf-btn-default waf-rules-refresh" href="#" role="button"><?php esc_html_e('Manually Refresh Rules', 'wordfence'); ?></a> </li> <li class="wf-padding-add-top-xs-small"><em id="waf-rules-next-update"></em></li> </ul> <script type="application/javascript"> (function($) { $('.waf-rules-refresh').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.wafUpdateRules(); }); })(jQuery); <?php try { $lastUpdated = wfWAF::getInstance()->getStorageEngine()->getConfig('rulesLastUpdated', null, 'transient'); $nextUpdate = PHP_INT_MAX; $cron = (array) wfWAF::getInstance()->getStorageEngine()->getConfig('cron', null, 'livewaf'); if (is_array($cron)) { /** @var wfWAFCronEvent $event */ foreach ($cron as $index => $event) { if ($event instanceof wfWAFCronFetchRulesEvent) { $event->setWaf(wfWAF::getInstance()); if (!$event->isInPast()) { $nextUpdate = min($nextUpdate, $event->getFireTime()); } } } } } catch (wfWAFStorageFileException $e) { error_log($e->getMessage()); } catch (wfWAFStorageEngineMySQLiException $e) { error_log($e->getMessage()); } if (!empty($lastUpdated)): ?> var lastUpdated = <?php echo (int) $lastUpdated ?>; WFAD.renderWAFRulesLastUpdated(new Date(lastUpdated * 1000)); <?php endif ?> <?php if ($nextUpdate < PHP_INT_MAX): ?> var nextUpdate = <?php echo (int) $nextUpdate ?>; WFAD.renderWAFRulesNextUpdate(new Date(nextUpdate * 1000)); <?php endif ?> </script> </li> <?php endif ?> </ul>PK �~\2"X�# �# waf-install.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?> <script type="text/x-jquery-template" id="wafTmpl_install"> <div class="wf-modal"> <div class="wf-modal-header"> <div class="wf-modal-header-content"> <div class="wf-modal-title"> <strong><?php esc_html_e('Optimize Wordfence Firewall', 'wordfence'); ?></strong> </div> </div> <div class="wf-modal-header-action"> <div><?php esc_html_e('If you cannot complete the setup process, ', 'wordfence'); ?><a target="_blank" rel="noopener noreferrer" href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_INSTALL_MANUALLY); ?>"><?php esc_html_e('click here for help', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></div> <div class="wf-padding-add-left-small wf-modal-header-action-close"><a href="#" onclick="WFAD.colorboxClose(); return false" role="button"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div> </div> </div> <div class="wf-modal-content"> <?php $currentAutoPrependFile = ini_get('auto_prepend_file'); if (empty($currentAutoPrependFile) || WF_IS_WP_ENGINE || WF_IS_PRESSABLE || WF_IS_FLYWHEEL): ?> <p><?php echo wp_kses(__('To make your site as secure as possible, the Wordfence Web Application Firewall is designed to run via a PHP setting called <code>auto_prepend_file</code>, which ensures it runs before any potentially vulnerable code runs.', 'wordfence'), array('code'=>array())); ?></p> <?php else: ?> <p><?php echo wp_kses(__('To make your site as secure as possible, the Wordfence Web Application Firewall is designed to run via a PHP setting called <code>auto_prepend_file</code>, which ensures it runs before any potentially vulnerable code runs. This PHP setting is currently in use, and is including this file:', 'wordfence'), array('code'=>array())); ?></p> <pre class='wf-pre'><?php echo esc_html($currentAutoPrependFile); ?></pre> <p><?php echo wp_kses(__('If you don\'t recognize this file, please <a href="https://wordpress.org/support/plugin/wordfence" target="_blank" rel="noopener noreferrer">contact us on the WordPress support forums<span class="screen-reader-text"> (opens in new tab)</span></a> before proceeding.', 'wordfence'), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p> <p><?php echo wp_kses(__('You can proceed with the installation and we will include this from within our <code>wordfence-waf.php</code> file which should maintain compatibility with your site, or you can opt to override the existing PHP setting.', 'wordfence'), array('code'=>array())); ?></p> <ul id="wf-waf-include-prepend" class="wf-switch"><li class="wf-active" data-option-value="include"><?php esc_html_e('Include', 'wordfence'); ?></li><li data-option-value="override"><?php esc_html_e('Override', 'wordfence'); ?></li></ul> <?php endif; ?> <div class="wf-notice"><strong><?php esc_html_e('NOTE:', 'wordfence'); ?></strong> <?php esc_html_e('If you have separate WordPress installations with Wordfence installed within a subdirectory of this site, it is recommended that you perform the Firewall installation procedure on those sites before this one.', 'wordfence'); ?></div> <?php $serverInfo = wfWebServerInfo::createFromEnvironment(); $dropdown = array( array("apache-mod_php", __('Apache + mod_php', 'wordfence'), $serverInfo->isApacheModPHP(), wfWAFAutoPrependHelper::helper('apache-mod_php')->getFilesNeededForBackup()), array("apache-suphp", __('Apache + suPHP', 'wordfence'), $serverInfo->isApacheSuPHP(), wfWAFAutoPrependHelper::helper('apache-suphp')->getFilesNeededForBackup()), array("cgi", __('Apache + CGI/FastCGI', 'wordfence'), $serverInfo->isApache() && !$serverInfo->isApacheSuPHP() && ($serverInfo->isCGI() || $serverInfo->isFastCGI()), wfWAFAutoPrependHelper::helper('cgi')->getFilesNeededForBackup()), array("litespeed", __('LiteSpeed/lsapi', 'wordfence'), $serverInfo->isLiteSpeed(), wfWAFAutoPrependHelper::helper('litespeed')->getFilesNeededForBackup()), array("nginx", __('NGINX', 'wordfence'), $serverInfo->isNGINX(), wfWAFAutoPrependHelper::helper('nginx')->getFilesNeededForBackup()), array("iis", __('Windows (IIS)', 'wordfence'), $serverInfo->isIIS(), wfWAFAutoPrependHelper::helper('iis')->getFilesNeededForBackup()), array("manual", __('Manual Configuration', 'wordfence'), false, array()), ); $hasRecommendedOption = false; $wafPrependOptions = ''; foreach ($dropdown as $option) { list($optionValue, $optionText, $selected) = $option; $optionValue=esc_attr($optionValue); $optionText=esc_html($optionText); $wafPrependOptions .= "<option value=\"{$optionValue}\"" . ($selected ? ' selected' : '') . ">{$optionText}" . ($selected ? ' (recommended based on our tests)' : '') . "</option>\n"; if ($selected) { $hasRecommendedOption = true; } } if (!$hasRecommendedOption): ?> <p><?php esc_html_e('If you know your web server\'s configuration, please select it from the list below.', 'wordfence'); ?></p> <?php else: ?> <p><?php esc_html_e('We\'ve preselected your server configuration based on our tests, but if you know your web server\'s configuration, please select it now. You can also choose "Manual Configuration" for alternate installation details.', 'wordfence'); ?></p> <?php endif; ?> <select name='serverConfiguration' id='wf-waf-server-config'> <?php echo $wafPrependOptions; ?> </select> <div class="wf-notice wf-nginx-waf-config" style="display: none;"><?php wp_kses(printf(/* translators: 1. PHP ini setting. 2. Support URL. */ __('Part of the Firewall configuration procedure for NGINX depends on creating a <code>%1$s</code> file in the root of your WordPress installation. This file can contain sensitive information and public access to it should be restricted. We have <a href="%2$s" target="_blank" rel="noreferrer noopener">instructions on our documentation site<span class="screen-reader-text"> (opens in new tab)</span></a> on what directives to put in your nginx.conf to fix this.', 'wordfence'), esc_html(ini_get('user_ini.filename') ? ini_get('user_ini.filename') : '(.user.ini)'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_INSTALL_NGINX)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></div> <div class="wf-manual-waf-config" style="display: none;"> <p><?php esc_html_e('If you are using a web server not listed in the dropdown or if file permissions prevent the installer from completing successfully, you will need to perform the change manually. Click Continue below to create the required file and view manual installation instructions.', 'wordfence'); ?></p> </div> <?php $adminURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options&action=configureAutoPrepend'); $wfnonce = wp_create_nonce('wfWAFAutoPrepend'); foreach ($dropdown as $option): list($optionValue, $optionText, $selected) = $option; $class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue); $helper = new wfWAFAutoPrependHelper($optionValue, null); $backups = $helper->getFilesNeededForBackup(); $filteredBackups = array(); foreach ($backups as $index => $backup) { if (!file_exists($backup)) { continue; } $filteredBackups[$index] = $backup; } $jsonBackups = json_encode(array_map('basename', $filteredBackups)); ?> <div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>"> <?php if (count($filteredBackups)): ?><p><?php esc_html_e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p><?php endif; ?> <ul class="wf-waf-backup-file-list"> <?php foreach ($filteredBackups as $index => $backup) { echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' . esc_url(add_query_arg(array( 'downloadBackup' => 1, 'backupIndex' => $index, 'serverConfiguration' => $helper->getServerConfig(), 'wfnonce' => $wfnonce, ), $adminURL)) . '">' . esc_html(sprintf(/* translators: File path. */ __('Download %s', 'wordfence'), basename($backup))) . '</a></li>'; } ?> </ul> </div> <?php endforeach; ?> </div> <div class="wf-modal-footer"> <ul class="wf-flex-horizontal wf-flex-full-width"> <li class="wf-waf-download-instructions"><?php esc_html_e('Once you have downloaded the files, click Continue to complete the setup.', 'wordfence'); ?></li> <li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-install-continue" role="button"><?php esc_html_e('Continue', 'wordfence'); ?></a></li> </ul> </div> </div> </script>PK �~\�X�y y option-rate-limit.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents a rate limit option with popup menus for limit value and action selections. * * Expects $rateOptionName, $rateOptions, $rateValue, $actionOptionName, $actionOptions, $actionValue, and $title to be defined. $helpLink may also be defined. * * @var string $rateOptionName The option name for the rate portion. * @var array $rateOptions An array of the possible values for $rateOptionName. The array is of the format array(array('value' => <the internal value>, 'label' => <a display label>), ...) * @var string $rateValue The current value of $rateOptionName. * @var int $lowValue The value below which the false positive warning should begin showing * @var string $actionOptionName The option name for the rate portion. * @var array $actionOptions An array of the possible values for $actionOptionName. The array is of the format array(array('value' => <the internal value>, 'label' => <a display label>), ...) * @var string $actionValue The current value of $actionOptionName. * @var string $title The title shown for the option. * @var string $helpLink If defined, the link to the corresponding external help page. * @var bool $premium If defined, the option will be tagged as premium only and not allow its value to change for free users. */ $rateID = 'wf-option-' . preg_replace('/[^a-z0-9]/i', '-', $rateOptionName); $actionID = 'wf-option-' . preg_replace('/[^a-z0-9]/i', '-', $actionOptionName); ?> <ul class="wf-option wf-option-rate-limit<?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' wf-option-premium'; } ?>" data-rate-option="<?php echo esc_attr($rateOptionName); ?>" data-original-rate-value="<?php echo esc_attr($rateValue); ?>" data-action-option="<?php echo esc_attr($actionOptionName); ?>" data-original-action-value="<?php echo esc_attr($actionValue); ?>" data-low-value="<?php echo (int) $lowValue; ?>"> <li class="wf-option-spacer"></li> <li class="wf-option-content"> <ul> <li class="wf-option-title"><span id="<?php echo esc_attr($rateID); ?>-label"><?php echo esc_html($title); ?></span><?php if (!wfConfig::p() && isset($premium) && $premium) { echo ' <a href="https://www.wordfence.com/gnl1optionUpgrade/wordfence-signup/" target="_blank" rel="noopener noreferrer" class="wf-premium-link">' . esc_html__('Premium Feature', 'wordfence') . '</a>'; } ?><?php if (isset($helpLink)) { echo ' <a href="' . esc_attr($helpLink) . '" target="_blank" rel="noopener noreferrer" class="wf-inline-help"><i class="wf-fa wf-fa-question-circle-o" aria-hidden="true"></i><span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>'; } ?></li> <li class="wf-option-select wf-left-xs wf-padding-add-top-xs-small wf-nowrap"> <select<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> id="<?php echo esc_attr($rateID); ?>" class="wf-rate-limit-rate" aria-labelledby="<?php echo esc_attr($rateID); ?>-label"> <?php foreach ($rateOptions as $o): ?> <option class="wf-option-select-option" value="<?php echo esc_attr($o['value']); ?>"<?php if ($o['value'] == $rateValue) { echo ' selected'; } ?>><?php echo esc_html($o['label']); ?></option> <?php endforeach; ?> </select> <span class="wf-padding-add-left-small wf-padding-add-right-small wf-padding-add-top-xs-small wf-padding-add-bottom-xs-small wf-inline-block-xs"><?php esc_html_e('then', 'wordfence'); ?></span> <select<?php echo (!(!wfConfig::p() && isset($premium) && $premium) ? '' : ' disabled'); ?> id="<?php echo esc_attr($actionID); ?>" class="wf-rate-limit-action" aria-labelledby="<?php echo esc_attr($rateID); ?>-label"> <?php foreach ($actionOptions as $o): ?> <option class="wf-option-select-option" value="<?php echo esc_attr($o['value']); ?>"<?php if ($o['value'] == $actionValue) { echo ' selected'; } ?>><?php echo esc_html($o['label']); ?></option> <?php endforeach; ?> </select> <div class="wf-rate-limit-warning"><div class="wf-inline-notice"><i class="wf-fa wf-fa-exclamation-triangle" aria-hidden="true"></i><span>Very strict. May cause false positives.</span></div></div> </li> </ul> </li> </ul>PK �~\��� waf-install-manual.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the manual message for WAF auto prepend installation. * */ ?> <p><?php echo wp_kses(__('The required file has been created. You\'ll need to insert the following code into your <code>php.ini</code> to finish installation:', 'wordfence'), array('code'=>array())); ?></p> <pre class="wf-pre">auto_prepend_file = '<?php echo esc_html(addcslashes(wordfence::getWAFBootstrapPath(), "'")); ?>'</pre> <p><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('You can find more details on alternative setup steps, including installation on SiteGround or for multiple sites sharing a single php.ini, <a target="_blank" rel="noopener noreferrer" href="%s">in our documentation<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_INSTALL_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p>PK �~\z���� � waf-uninstall.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } ?> <script type="text/x-jquery-template" id="wafTmpl_uninstall"> <div class="wf-modal"> <div class="wf-modal-header"> <div class="wf-modal-header-content"> <div class="wf-modal-title"> <strong><?php esc_html_e('Uninstall Wordfence Firewall', 'wordfence'); ?></strong> </div> </div> <div class="wf-modal-header-action"> <div><?php echo wp_kses(sprintf(__('If you cannot complete the uninstall process, <a target="_blank" rel="noopener noreferrer" href="%s">click here for help<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_REMOVE_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></div> <div class="wf-padding-add-left-small wf-modal-header-action-close"><a href="#" onclick="WFAD.colorboxClose(); return false" role="button"><i class="wf-fa wf-fa-times-circle" aria-hidden="true"></i></a></div> </div> </div> <div class="wf-modal-content"> <?php if (WF_IS_WP_ENGINE || WF_IS_PRESSABLE || WF_IS_FLYWHEEL) { $currentAutoPrependFile = wordfence::getWAFBootstrapPath(); } else { $currentAutoPrependFile = ini_get('auto_prepend_file'); } ?> <p><?php echo wp_kses(__('Extended Protection Mode of the Wordfence Web Application Firewall uses the PHP ini setting called <code>auto_prepend_file</code> in order to ensure it runs before any potentially vulnerable code runs. This PHP setting currently refers to the Wordfence file at:', 'wordfence'), array('code'=>array())); ?></p> <pre class='wf-pre'><?php echo esc_html($currentAutoPrependFile); ?></pre> <?php $contents = file_get_contents($currentAutoPrependFile); $refersToWAF = preg_match('/define\s*\(\s*(["\'])WFWAF_LOG_PATH\1\s*,\s*(__DIR__\s*\.\s*)?(["\']).+?\3\s*\)\s*/', $contents); if (!$refersToWAF): ?> <p><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('Automatic uninstallation cannot be completed, but you may still be able to <a href="%s" target="_blank" rel="noopener noreferrer">manually uninstall extended protection<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_REMOVE_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p> <?php else: ?> <p><?php echo wp_kses(__('Before this file can be deleted, the configuration for the <code>auto_prepend_file</code> setting needs to be removed.', 'wordfence'), array('code'=>array())); ?></p> <?php $serverInfo = wfWebServerInfo::createFromEnvironment(); $dropdown = array( array("apache-mod_php", __('Apache + mod_php', 'wordfence'), $serverInfo->isApacheModPHP(), wfWAFAutoPrependHelper::helper('apache-mod_php')->getFilesNeededForBackup()), array("apache-suphp", __('Apache + suPHP', 'wordfence'), $serverInfo->isApacheSuPHP(), wfWAFAutoPrependHelper::helper('apache-suphp')->getFilesNeededForBackup()), array("cgi", __('Apache + CGI/FastCGI', 'wordfence'), $serverInfo->isApache() && !$serverInfo->isApacheSuPHP() && ($serverInfo->isCGI() || $serverInfo->isFastCGI()), wfWAFAutoPrependHelper::helper('cgi')->getFilesNeededForBackup()), array("litespeed", __('LiteSpeed/lsapi', 'wordfence'), $serverInfo->isLiteSpeed(), wfWAFAutoPrependHelper::helper('litespeed')->getFilesNeededForBackup()), array("nginx", __('NGINX', 'wordfence'), $serverInfo->isNGINX(), wfWAFAutoPrependHelper::helper('nginx')->getFilesNeededForBackup()), array("iis", __('Windows (IIS)', 'wordfence'), $serverInfo->isIIS(), wfWAFAutoPrependHelper::helper('iis')->getFilesNeededForBackup()), ); $hasRecommendedOption = false; $wafPrependOptions = ''; foreach ($dropdown as $option) { list($optionValue, $optionText, $selected) = $option; $optionValue=esc_attr($optionValue); $optionText=esc_html($optionText); $wafPrependOptions .= "<option value=\"{$optionValue}\"" . ($selected ? ' selected' : '') . ">{$optionText}" . ($selected ? ' (recommended based on our tests)' : '') . "</option>\n"; if ($selected) { $hasRecommendedOption = true; } } if (!$hasRecommendedOption): ?> <p><?php esc_html_e('If you know your web server\'s configuration, please select it from the list below.', 'wordfence'); ?></p> <?php else: ?> <p><?php esc_html_e('We\'ve preselected your server configuration based on our tests, but if you know your web server\'s configuration, please select it now.', 'wordfence'); ?></p> <?php endif; ?> <select name='serverConfiguration' id='wf-waf-server-config'> <?php echo $wafPrependOptions; ?> </select> <?php $adminURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options&action=removeAutoPrepend'); $wfnonce = wp_create_nonce('wfWAFRemoveAutoPrepend'); foreach ($dropdown as $option): list($optionValue, $optionText, $selected) = $option; $class = preg_replace('/[^a-z0-9\-]/i', '', $optionValue); $helper = new wfWAFAutoPrependHelper($optionValue, null); $backups = $helper->getFilesNeededForBackup(); $filteredBackups = array(); foreach ($backups as $index => $backup) { if (!file_exists($backup)) { continue; } $filteredBackups[$index] = $backup; } $jsonBackups = json_encode(array_map('basename', $filteredBackups)); ?> <div class="wf-waf-backups wf-waf-backups-<?php echo $class; ?>" style="display: none;" data-backups="<?php echo esc_attr($jsonBackups); ?>"> <?php if (count($filteredBackups)): ?><p><?php esc_html_e('Please download a backup of the following files before we make the necessary changes:', 'wordfence'); ?></p><?php endif; ?> <ul class="wf-waf-backup-file-list"> <?php foreach ($filteredBackups as $index => $backup) { echo '<li><a class="wf-btn wf-btn-default wf-waf-backup-download" data-backup-index="' . $index . '" href="' . esc_url(add_query_arg(array( 'downloadBackup' => 1, 'backupIndex' => $index, 'serverConfiguration' => $helper->getServerConfig(), 'wfnonce' => $wfnonce, ), $adminURL)) . '">' . esc_html(sprintf(__('Download %s', 'wordfence'), basename($backup))) . '</a></li>'; } ?> </ul> </div> <?php endforeach; ?> <?php endif; ?> </div> <div class="wf-modal-footer"> <ul class="wf-flex-horizontal wf-flex-full-width"> <li class="wf-waf-download-instructions"><?php esc_html_e('Once you have downloaded the files, click Continue to complete uninstallation.', 'wordfence'); ?></li> <li class="wf-right"><a href="#" class="wf-btn wf-btn-primary wf-btn-callout-subtle wf-disabled" id="wf-waf-uninstall-continue" role="button"><?php esc_html_e('Continue', 'wordfence'); ?></a></li> </ul> </div> </div> </script>PK �~\�W�{C4 C4 options-group-rate-limiting.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the Rate Limiting group. * * Expects $firewall, $waf, and $stateKey. * * @var wfFirewall $firewall * @var wfWAF $waf * @var string $stateKey The key under which the collapse state is stored. * @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true. */ $config = $waf->getStorageEngine(); if (!isset($collapseable)) { $collapseable = true; } ?> <div class="wf-row"> <div class="wf-col-xs-12"> <div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>"> <div class="wf-block-header"> <div class="wf-block-header-content"> <div class="wf-block-title"> <strong><?php esc_html_e('Rate Limiting', 'wordfence'); ?></strong> </div> <?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?> </div> </div> <div class="wf-block-content"> <ul class="wf-block-list"> <li> <?php echo wfView::create('options/option-switch', array( 'optionName' => 'firewallEnabled', 'value' => wfConfig::get('firewallEnabled') ? '1': '0', 'title' => __('Enable Rate Limiting and Advanced Blocking', 'wordfence'), 'subtitle' => __('NOTE: This checkbox enables ALL blocking/throttling functions including IP, country and advanced blocking, and the "Rate Limiting Rules" below.', 'wordfence'), 'states' => array( array('value' => '0', 'label' => __('Off', 'wordfence')), array('value' => '1', 'label' => __('On', 'wordfence')), ), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_ENABLE_ADVANCED_BLOCKING), 'noSpacer' => true, 'alignment' => 'wf-right', ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-select', array( 'selectOptionName' => 'neverBlockBG', 'selectOptions' => array( array('value' => 'neverBlockVerified', 'label' => __('Verified Google crawlers will not be rate-limited', 'wordfence')), array('value' => 'neverBlockUA', 'label' => __('Anyone claiming to be Google will not be rate-limited', 'wordfence')), array('value' => 'treatAsOtherCrawlers', 'label' => __('Treat Google like any other Crawler', 'wordfence')), ), 'selectValue' => wfConfig::get('neverBlockBG'), 'title' => __('How should we treat Google\'s crawlers', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_GOOGLE_ACTION), ))->render(); ?> </li> <?php $rateOptions = array( array('value' => 'DISABLED', 'label' => __('Unlimited', 'wordfence')), array('value' => 1920, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 1920)), array('value' => 960, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 960)), array('value' => 480, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 480)), array('value' => 240, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 240)), array('value' => 120, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 120)), array('value' => 60, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 60)), array('value' => 30, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 30)), array('value' => 15, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 15)), array('value' => 10, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 10)), array('value' => 5, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 5)), array('value' => 4, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 4)), array('value' => 3, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 3)), array('value' => 2, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 2)), array('value' => 1, 'label' => sprintf(/* translators: Number of HTTP requests. */__('%d per minute', 'wordfence'), 1)), ); $actionOptions = array( array('value' => 'throttle', 'label' => __('throttle it', 'wordfence')), array('value' => 'block', 'label' => __('block it', 'wordfence')), ); ?> <li> <?php echo wfView::create('waf/option-rate-limit', array( 'toggleOptionName' => 'maxGlobalRequests_enabled', 'toggleValue' => !!wfConfig::get('maxGlobalRequests_enabled') ? 1 : 0, 'rateOptionName' => 'maxGlobalRequests', 'rateOptions' => $rateOptions, 'rateValue' => wfConfig::get('maxGlobalRequests'), 'lowValue' => 120, 'actionOptionName' => 'maxGlobalRequests_action', 'actionOptions' => $actionOptions, 'actionValue' => wfConfig::get('maxGlobalRequests_action'), 'title' => __('If anyone\'s requests exceed', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_ANY), ))->render(); ?> </li> <li> <?php echo wfView::create('waf/option-rate-limit', array( 'toggleOptionName' => 'maxRequestsCrawlers_enabled', 'toggleValue' => !!wfConfig::get('maxRequestsCrawlers_enabled') ? 1 : 0, 'rateOptionName' => 'maxRequestsCrawlers', 'rateOptions' => $rateOptions, 'rateValue' => wfConfig::get('maxRequestsCrawlers'), 'lowValue' => 120, 'actionOptionName' => 'maxRequestsCrawlers_action', 'actionOptions' => $actionOptions, 'actionValue' => wfConfig::get('maxRequestsCrawlers_action'), 'title' => __('If a crawler\'s page views exceed', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_CRAWLER), ))->render(); ?> </li> <li> <?php echo wfView::create('waf/option-rate-limit', array( 'toggleOptionName' => 'max404Crawlers_enabled', 'toggleValue' => !!wfConfig::get('max404Crawlers_enabled') ? 1 : 0, 'rateOptionName' => 'max404Crawlers', 'rateOptions' => $rateOptions, 'rateValue' => wfConfig::get('max404Crawlers'), 'lowValue' => 60, 'actionOptionName' => 'max404Crawlers_action', 'actionOptions' => $actionOptions, 'actionValue' => wfConfig::get('max404Crawlers_action'), 'title' => __('If a crawler\'s pages not found (404s) exceed', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_CRAWLER_404), ))->render(); ?> </li> <li> <?php echo wfView::create('waf/option-rate-limit', array( 'toggleOptionName' => 'maxRequestsHumans_enabled', 'toggleValue' => !!wfConfig::get('maxRequestsHumans_enabled') ? 1 : 0, 'rateOptionName' => 'maxRequestsHumans', 'rateOptions' => $rateOptions, 'rateValue' => wfConfig::get('maxRequestsHumans'), 'lowValue' => 120, 'actionOptionName' => 'maxRequestsHumans_action', 'actionOptions' => $actionOptions, 'actionValue' => wfConfig::get('maxRequestsHumans_action'), 'title' => __('If a human\'s page views exceed', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_HUMAN), ))->render(); ?> </li> <li> <?php echo wfView::create('waf/option-rate-limit', array( 'toggleOptionName' => 'max404Humans_enabled', 'toggleValue' => !!wfConfig::get('max404Humans_enabled') ? 1 : 0, 'rateOptionName' => 'max404Humans', 'rateOptions' => $rateOptions, 'rateValue' => wfConfig::get('max404Humans'), 'lowValue' => 60, 'actionOptionName' => 'max404Humans_action', 'actionOptions' => $actionOptions, 'actionValue' => wfConfig::get('max404Humans_action'), 'title' => __('If a human\'s pages not found (404s) exceed', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_RATE_LIMIT_HUMAN_404), ))->render(); ?> </li> <li> <?php $breakpoints = array(60, 300, 1800, 3600, 7200, 21600, 43200, 86400, 172800, 432000, 864000, 2592000); $options = array(); foreach ($breakpoints as $b) { $options[] = array('value' => $b, 'label' => wfUtils::makeDuration($b)); } echo wfView::create('options/option-select', array( 'selectOptionName' => 'blockedTime', 'selectOptions' => $options, 'selectValue' => wfConfig::getInt('blockedTime'), 'title' => __('How long is an IP address blocked when it breaks a rule', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_AUTOMATIC_BLOCK_DURATION), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-textarea', array( 'textOptionName' => 'allowed404s', 'textValue' => wfUtils::cleanupOneEntryPerLine(wfConfig::get('allowed404s')), 'title' => __('Allowlisted 404 URLs', 'wordfence'), 'subtitle' => __('These URL patterns will be excluded from the throttling rules used to limit crawlers.', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_WHITELISTED_404), ))->render(); ?> </li> </ul> <script type="application/javascript"> (function($) { WFAD.updateRateLimitDisplay = function(value, lowValue, warningElement) { var hide = true; if (Number.isNaN) { //Anything except IE var originalRateValue = Number.parseInt(value); var lowValue = Number.parseInt(lowValue); if (!Number.isNaN(originalRateValue) && !Number.isNaN(lowValue)) { if (originalRateValue < lowValue) { hide = false; } } } else { //IE var originalRateValue = parseInt(value); var lowValue = parseInt(lowValue); if (!isNaN(originalRateValue) && !isNaN(lowValue)) { if (originalRateValue < lowValue) { hide = false; } } } $(warningElement).css('display', hide ? 'none' : 'block'); }; $(function() { $('.wf-option.wf-option-rate-limit > .wf-option-content > ul > li.wf-option-select select').wfselect2({ minimumResultsForSearch: -1 }).on('change', function () { var optionElement = $(this).closest('.wf-option'); if ($(this).hasClass('wf-rate-limit-rate')) { var option = optionElement.data('rateOption'); var value = $(this).val(); var originalValue = optionElement.data('originalRateValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } WFAD.updateRateLimitDisplay(value, $(optionElement).data('lowValue'), $(optionElement).find('.wf-rate-limit-warning')); } else if ($(this).hasClass('wf-rate-limit-action')) { var option = optionElement.data('actionOption'); var value = $(this).val(); var originalValue = optionElement.data('originalActionValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } } WFAD.updatePendingChanges(); }).triggerHandler('change'); $(window).on('wfOptionsReset', function() { $('.wf-option.wf-option-rate-limit').each(function() { var originalRateValue = $(this).data('originalRateValue'); $(this).find('.wf-rate-limit-rate').val(originalRateValue).trigger('change'); var originalActionValue = $(this).data('originalActionValue'); $(this).find('.wf-rate-limit-action').val(originalActionValue).trigger('change'); WFAD.updateRateLimitDisplay($(this).data('originalRateValue'), $(this).data('lowValue'), $(this).find('.wf-rate-limit-warning')); }); }); //Initial warning display $('.wf-option.wf-option-rate-limit').each(function() { WFAD.updateRateLimitDisplay($(this).data('originalRateValue'), $(this).data('lowValue'), $(this).find('.wf-rate-limit-warning')); }); }); })(jQuery); </script> </div> </div> </div> </div> <!-- end rate limiting -->PK �~\���D� � firewall-status.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the firewall status. * * Expects $firewall and $dashboard to be defined. * * @var wfFirewall $firewall The firewall state. * @var wfDashboard $dashboard Dashboard statistics. */ ?> <ul class="wf-block-list wf-block-list-horizontal"> <?php if ($firewall->firewallMode() == 'enabled' && $firewall->ruleMode() == wfFirewall::RULE_MODE_PREMIUM): ?> <li> <div class="wf-block-labeled-value wf-waf-status wf-waf-status-full-enabled"> <div class="wf-block-labeled-value-label"><?php switch (wfLicense::current()->getType()) { case wfLicense::TYPE_RESPONSE: esc_html_e('Wordfence Firewall & Response License Enabled', 'wordfence'); break; case wfLicense::TYPE_CARE: esc_html_e('Wordfence Firewall & Care License Enabled', 'wordfence'); break; default: esc_html_e('Wordfence Firewall & Premium Enabled', 'wordfence'); break; } ?></div> </div> </li> <?php else: ?> <li> <?php if ($firewall->firewallMode() == wfFirewall::FIREWALL_MODE_DISABLED): ?> <div class="wf-waf-status-disabled"> <p><h3><?php esc_html_e('Wordfence Firewall Deactivated', 'wordfence'); ?></h3></p> <p><?php esc_html_e('The Wordfence Web Application Firewall is a PHP-based, application-level firewall that filters out malicious requests to your site. It is designed to run at the beginning of WordPress\' initialization to filter any attacks before plugins or themes can run any potentially vulnerable code.', 'wordfence'); ?></p> <p> <a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="#" target="_blank" rel="noopener noreferrer" id="waf-top-enable-firewall" role="button"><?php esc_html_e('Enable Firewall', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a> <script type="application/javascript"> (function($) { $(function() { $('#waf-top-enable-firewall').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.setOption('wafStatus', 'enabled', function() { window.location.reload(true); }); }); }); })(jQuery); </script> </p> </div> <?php else: ?> <?php if ($firewall->firewallMode() == wfFirewall::FIREWALL_MODE_ENABLED): ?> <div class="wf-block-labeled-value wf-waf-status wf-waf-status-<?php echo esc_attr($firewall->firewallMode()); ?>"> <div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div> <div class="wf-block-labeled-value-label"><?php esc_html_e('Wordfence Firewall Activated', 'wordfence'); ?></div> </div> <?php elseif ($firewall->firewallMode() == wfFirewall::FIREWALL_MODE_LEARNING): ?> <div> <?php $learningMode = $firewall->learningModeStatus(); if (function_exists('network_admin_url') && is_multisite()) { $optionsURL = network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options'); } else { $optionsURL = admin_url('admin.php?page=WordfenceWAF&subpage=waf_options'); } ?> <p><h3><?php echo ($learningMode === true ? esc_html__('Learning Mode Enabled', 'wordfence') : esc_html(sprintf(/* translators: Localized date. */ __('Learning Mode Until %s', 'wordfence'), wfUtils::formatLocalTime(get_option('date_format'), $learningMode)))); ?></h3></p> <p><?php echo wp_kses(__('<i class="wf-fa wf-fa-lightbulb-o wf-tip" aria-hidden="true"></i> When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall.', 'wordfence'), array('i'=>array('class'=>array()))); ?></p> <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="<?php echo esc_url($optionsURL); ?>"><?php esc_html_e('Manage Firewall', 'wordfence'); ?></a> <a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="<?php echo wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></p> </div> <?php endif; ?> <?php endif; ?> </li> <li> <?php if ($firewall->ruleMode() == wfFirewall::RULE_MODE_COMMUNITY): ?> <div> <p><h3><?php esc_html_e('Premium Protection Disabled', 'wordfence'); ?></h3></p> <p><?php esc_html_e('As a free Wordfence user, you are currently using the Community version of the Threat Defense Feed. Premium users are protected by additional firewall rules and malware signatures. Upgrade to Premium today to improve your protection.', 'wordfence'); ?></p> <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1wafUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a> <a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1wafLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></p> </div> <?php else: ?> <div class="wf-block-labeled-value wf-protection-status wf-protection-status-<?php echo esc_attr($firewall->ruleMode()); ?>"> <div class="wf-block-labeled-value-value"><i class="wf-fa wf-fa-check" aria-hidden="true"></i></div> <div class="wf-block-labeled-value-label"><?php esc_html_e('Premium Protection Enabled', 'wordfence'); ?></div> </div> <?php endif; ?> </li> <?php endif; ?> </ul>PK �~\TO�hk2 k2 options-group-brute-force.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the Brute Force Protection group. * * Expects $firewall, $waf, and $stateKey. * * @var wfFirewall $firewall * @var wfWAF $waf * @var string $stateKey The key under which the collapse state is stored. * @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true. */ $config = $waf->getStorageEngine(); if (!isset($collapseable)) { $collapseable = true; } ?> <div class="wf-row"> <div class="wf-col-xs-12"> <div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>"> <div class="wf-block-header"> <div class="wf-block-header-content"> <div class="wf-block-title"> <strong><?php esc_html_e('Brute Force Protection', 'wordfence'); ?></strong> </div> <?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?> </div> </div> <div class="wf-block-content"> <ul class="wf-block-list"> <li> <?php echo wfView::create('options/option-switch', array( 'optionName' => 'loginSecurityEnabled', 'value' => wfConfig::get('loginSecurityEnabled') ? '1': '0', 'titleHTML' => '<strong>' . esc_html__('Enable brute force protection', 'wordfence') . '</strong>', 'subtitle' => __('This option enables all "Brute Force Protection" options, including strong password enforcement and invalid login throttling. You can modify individual options below.', 'wordfence'), 'states' => array( array('value' => '0', 'label' => __('Off', 'wordfence')), array('value' => '1', 'label' => __('On', 'wordfence')), ), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_ENABLE_LOGIN_SECURITY), 'noSpacer' => true, 'alignment' => 'wf-right', ))->render(); ?> </li> <li> <?php $breakpoints = array(2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 200, 500); $options = array(); foreach ($breakpoints as $b) { $options[] = array('value' => $b, 'label' => $b); } echo wfView::create('options/option-select', array( 'selectOptionName' => 'loginSec_maxFailures', 'selectOptions' => $options, 'selectValue' => wfConfig::get('loginSec_maxFailures'), 'title' => __('Lock out after how many login failures', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_LOCK_OUT_FAILURE_COUNT), ))->render(); ?> </li> <li> <?php $breakpoints = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 100, 200, 500); $options = array(); foreach ($breakpoints as $b) { $options[] = array('value' => $b, 'label' => $b); } echo wfView::create('options/option-select', array( 'selectOptionName' => 'loginSec_maxForgotPasswd', 'selectOptions' => $options, 'selectValue' => wfConfig::get('loginSec_maxForgotPasswd'), 'title' => __('Lock out after how many forgot password attempts', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_LOCK_OUT_FORGOT_PASSWORD_COUNT), ))->render(); ?> </li> <li> <?php $breakpoints = array(5, 10, 30, 60, 120, 240, 360, 720, 1440); $options = array(); foreach ($breakpoints as $b) { $options[] = array('value' => $b, 'label' => wfUtils::makeDuration($b * 60)); } echo wfView::create('options/option-select', array( 'selectOptionName' => 'loginSec_countFailMins', 'selectOptions' => $options, 'selectValue' => wfConfig::getInt('loginSec_countFailMins'), 'title' => __('Count failures over what time period', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_COUNT_TIME_PERIOD), ))->render(); ?> </li> <li> <?php $breakpoints = array(5, 10, 30, 60, 120, 240, 360, 720, 1440, 2880, 7200, 14400, 28800, 43200, 86400); $options = array(); foreach ($breakpoints as $b) { $options[] = array('value' => $b, 'label' => wfUtils::makeDuration($b * 60)); } echo wfView::create('options/option-select', array( 'selectOptionName' => 'loginSec_lockoutMins', 'selectOptions' => $options, 'selectValue' => wfConfig::getInt('loginSec_lockoutMins'), 'title' => __('Amount of time a user is locked out', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_LOCKOUT_DURATION), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'loginSec_lockInvalidUsers', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('loginSec_lockInvalidUsers') ? 1 : 0, 'title' => __('Immediately lock out invalid usernames', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_IMMEDIATELY_LOCK_OUT_INVALID_USERS), ))->render(); ?> </li> <li> <?php $blacklist = wfConfig::get('loginSec_userBlacklist', ''); if (empty($blacklist)) { $users = array(); } else { $users = explode("\n", wfUtils::cleanupOneEntryPerLine($blacklist)); } echo wfView::create('options/option-token', array( 'tokenOptionName' => 'loginSec_userBlacklist', 'tokenValue' => $users, 'title' => __('Immediately block the IP of users who try to sign in as these usernames', 'wordfence'), 'subtitle' => __('Hit enter to add a username', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_IMMEDIATELY_BLOCK_USERS), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled-select', array( 'toggleOptionName' => 'loginSec_breachPasswds_enabled', 'enabledToggleValue' => 1, 'disabledToggleValue' => 0, 'toggleValue' => !!wfConfig::get('loginSec_breachPasswds_enabled') ? 1 : 0, 'selectOptionName' => 'loginSec_breachPasswds', 'selectOptions' => array(array('value' => 'admins', 'label' => __('For admins only', 'wordfence')), array('value' => 'pubs', 'label' => __('For all users with "publish posts" capability', 'wordfence'))), 'selectValue' => wfConfig::get('loginSec_breachPasswds'), 'title' => __('Prevent the use of passwords leaked in data breaches', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PREVENT_BREACH_PASSWORDS), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-label', array( 'titleHTML' => '<strong>' . esc_html__('Additional Options', 'wordfence') . '</strong>', 'noSpacer' => true, ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled-select', array( 'toggleOptionName' => 'loginSec_strongPasswds_enabled', 'enabledToggleValue' => 1, 'disabledToggleValue' => 0, 'toggleValue' => !!wfConfig::get('loginSec_strongPasswds_enabled') ? 1 : 0, 'selectOptionName' => 'loginSec_strongPasswds', 'selectOptions' => array(array('value' => 'pubs', 'label' => __('Force admins and publishers to use strong passwords (recommended)', 'wordfence')), array('value' => 'all', 'label' => __('Force all members to use strong passwords', 'wordfence'))), 'selectValue' => wfConfig::get('loginSec_strongPasswds'), 'title' => __('Enforce strong passwords', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_ENFORCE_STRONG_PASSWORDS), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'loginSec_maskLoginErrors', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('loginSec_maskLoginErrors') ? 1 : 0, 'title' => __('Don\'t let WordPress reveal valid users in login errors', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_MASK_LOGIN_ERRORS), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'loginSec_blockAdminReg', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('loginSec_blockAdminReg') ? 1 : 0, 'title' => __('Prevent users registering \'admin\' username if it doesn\'t exist', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PREVENT_ADMIN_REGISTRATION), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'loginSec_disableAuthorScan', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('loginSec_disableAuthorScan') ? 1 : 0, 'title' => __('Prevent discovery of usernames through \'/?author=N\' scans, the oEmbed API, the WordPress REST API, and WordPress XML Sitemaps', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PREVENT_AUTHOR_SCAN), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'loginSec_disableApplicationPasswords', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('loginSec_disableApplicationPasswords') ? 1 : 0, 'title' => __('Disable WordPress application passwords', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_DISABLE_APPLICATION_PASSWORDS), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'other_blockBadPOST', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('other_blockBadPOST') ? 1 : 0, 'title' => __('Block IPs who send POST requests with blank User-Agent and Referer', 'wordfence'), 'subtitleHTML' => esc_html__('If you use external services that may send POST requests without these headers, do not use this option, as they will be blocked.', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_BLOCK_BAD_POST), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-textarea', array( 'textOptionName' => 'blockCustomText', 'textValue' => wfConfig::get('blockCustomText'), 'title' => __('Custom text shown on block pages', 'wordfence'), 'alignTitle' => 'top', 'subtitleHTML' => esc_html__('HTML tags will be stripped prior to output and line breaks will be converted into the appropriate tags.', 'wordfence'), 'subtitlePosition' => 'value', 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_CUSTOM_BLOCK_TEXT), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'other_pwStrengthOnUpdate', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('other_pwStrengthOnUpdate') ? 1 : 0, 'title' => __('Check password strength on profile update', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_CHECK_PASSWORD), ))->render(); ?> </li> <li> <?php echo wfView::create('options/option-toggled', array( 'optionName' => 'other_WFNet', 'enabledValue' => 1, 'disabledValue' => 0, 'value' => wfConfig::get('other_WFNet') ? 1 : 0, 'title' => __('Participate in the Real-Time Wordfence Security Network', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_OPTION_PARTICIPATE_WFSN), ))->render(); ?> </li> </ul> </div> </div> </div> </div> <!-- end brute force protection -->PK �~\�j�l l options-group-basic-firewall.phpnu �[��� <?php if (!defined('WORDFENCE_VERSION')) { exit; } /** * Presents the Basic Firewall Options group. * * Expects $firewall, $waf, and $stateKey. * * @var wfFirewall $firewall * @var wfWAF $waf * @var string $stateKey The key under which the collapse state is stored. * @var bool $collapseable If defined, specifies whether or not this grouping can be collapsed. Defaults to true. */ $config = $waf->getStorageEngine(); if (!isset($collapseable)) { $collapseable = true; } ?> <div class="wf-row"> <div class="wf-col-xs-12"> <div class="wf-block<?php if (!$collapseable) { echo ' wf-always-active'; } else { echo (wfPersistenceController::shared()->isActive($stateKey) ? ' wf-active' : ''); } ?>" data-persistence-key="<?php echo esc_attr($stateKey); ?>"> <div class="wf-block-header"> <div class="wf-block-header-content"> <div class="wf-block-title"> <strong><?php esc_html_e('Basic Firewall Options', 'wordfence'); ?></strong> </div> <?php if ($collapseable): ?><div class="wf-block-header-action"><div class="wf-block-header-action-disclosure" role="checkbox" aria-checked="<?php echo (wfPersistenceController::shared()->isActive($stateKey) ? 'true' : 'false'); ?>" tabindex="0"></div></div><?php endif; ?> </div> </div> <div class="wf-block-content"> <ul class="wf-block-list wf-block-list-horizontal"> <li id="wf-option-wafStatus" class="wf-flex-vertical wf-flex-align-left wf-flex-full-width"> <h3><?php esc_html_e('Web Application Firewall Status', 'wordfence'); ?></h3> <?php if ($firewall->isSubDirectoryInstallation()): ?> <p class="wf-no-top"><?php echo wp_kses(sprintf(/* translators: WordPress admin URL. */ __('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please <a href="%s">click here</a> to configure the Firewall to run correctly on this site.', 'wordfence'), esc_attr(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#configureAutoPrepend'))), array('a'=>array('href'=>array()))); ?></p> <?php else: ?> <p class="wf-no-top"> <?php $wafStatus = $firewall->firewallMode(); ?> <span id="wafStatus-enabled-description" class="wafStatus-description"<?php if ($wafStatus != wfFirewall::FIREWALL_MODE_ENABLED) { echo ' style="display: none;"'; } ?>><strong><?php esc_html_e('Enabled and Protecting:', 'wordfence'); ?></strong> <?php esc_html_e('In this mode, the Wordfence Web Application Firewall is actively blocking requests matching known attack patterns and is actively protecting your site from attackers.', 'wordfence'); ?></span> <span id="wafStatus-learning-mode-description" class="wafStatus-description"<?php if ($wafStatus != wfFirewall::FIREWALL_MODE_LEARNING) { echo ' style="display: none;"'; } ?>><strong><?php esc_html_e('Learning Mode:', 'wordfence'); ?></strong> <?php echo wp_kses(sprintf(/* translators: Support URL. */ __('When you first install the Wordfence Web Application Firewall, it will be in learning mode. This allows Wordfence to learn about your site so that we can understand how to protect it and how to allow normal visitors through the firewall. We recommend you let Wordfence learn for a week before you enable the firewall. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More<span class="screen-reader-text"> (opens in new tab)</span></a>', 'wordfence'), wfSupportController::supportURL(wfSupportController::ITEM_FIREWALL_WAF_LEARNING_MODE)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></span> <span id="wafStatus-disabled-description" class="wafStatus-description"<?php if ($wafStatus != wfFirewall::FIREWALL_MODE_DISABLED) { echo ' style="display: none;"'; } ?>><strong><?php esc_html_e('Disabled:', 'wordfence'); ?></strong> <?php esc_html_e('In this mode, the Wordfence Web Application Firewall is functionally turned off and does not run any of its rules or analyze the request in any way.', 'wordfence'); ?></span> </p> <p class="wf-no-top wf-add-bottom"> <select id="input-wafStatus" data-original-value="<?php echo esc_attr($wafStatus); ?>" name="wafStatus" class="wf-form-control"<?php echo !WFWAF_ENABLED ? ' disabled' : '' ?>> <option<?php echo $wafStatus == wfFirewall::FIREWALL_MODE_ENABLED ? ' selected' : '' ?> class="wafStatus-enabled" value="enabled"><?php esc_html_e('Enabled and Protecting', 'wordfence'); ?></option> <option<?php echo $wafStatus == wfFirewall::FIREWALL_MODE_LEARNING ? ' selected' : '' ?> class="wafStatus-learning-mode" value="learning-mode"><?php esc_html_e('Learning Mode', 'wordfence'); ?></option> <option<?php echo $wafStatus == wfFirewall::FIREWALL_MODE_DISABLED ? ' selected' : '' ?> class="wafStatus-disabled" value="disabled"><?php esc_html_e('Disabled', 'wordfence'); ?></option> </select> <script type="application/javascript"> (function($) { $(function() { $('#input-wafStatus').wfselect2({ minimumResultsForSearch: -1, width: '200px' }).on('change', function() { var select = $(this); var value = select.val(); var container = $($(this).data('wfselect2').$container); container.removeClass('wafStatus-enabled wafStatus-learning-mode wafStatus-disabled') .addClass('wafStatus-' + value); $('.wafStatus-description').hide(); $('#wafStatus-' + value + '-description').show(); if (value == 'learning-mode') { $('#waf-learning-mode-grace-period').show(); } else { $('#waf-learning-mode-grace-period').hide(); } var originalValue = select.data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges['wafStatus']; } else { WFAD.pendingChanges['wafStatus'] = value; } WFAD.updatePendingChanges(); }).val(<?php echo json_encode($wafStatus) ?>).triggerHandler('change'); $('#waf-learning-mode-grace-period .wf-datetime').datetimepicker({ dateFormat: 'yy-mm-dd', timezone: <?php try { echo (int) wfUtils::timeZoneMinutes($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : false); } catch (Exception $e) { echo 0; }; ?>, showTime: false, showTimepicker: false, showMonthAfterYear: true }).each(function() { var el = $(this); if (el.attr('data-value')) { el.datetimepicker('setDate', new Date(el.attr('data-value') * 1000)); } }).on('change', function() { var value = Math.floor($(this).datetimepicker('getDate').getTime() / 1000); var originalValue = $('#input-learningModeGracePeriod').data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges['learningModeGracePeriod']; } else { WFAD.pendingChanges['learningModeGracePeriod'] = $(this).val(); } WFAD.updatePendingChanges(); }); $('#waf-learning-mode-grace-period .wf-option-checkbox').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var originalValue = $(this).data('originalValue'); var value = originalValue; var isActive = $(this).hasClass('wf-checked'); if (isActive) { $(this).removeClass('wf-checked'); $('#waf-learning-mode-grace-period .wf-datetime').attr('disabled', true); value = 0; } else { $(this).addClass('wf-checked'); $('#waf-learning-mode-grace-period .wf-datetime').attr('disabled', false); value = 1; if (!$('#input-learningModeGracePeriod').val()) { var date = new Date(); date.setDate(date.getDate() + 7); $('#input-learningModeGracePeriod').datetimepicker('setDate', date); } } if (originalValue == value) { delete WFAD.pendingChanges['learningModeGracePeriodEnabled']; } else { WFAD.pendingChanges['learningModeGracePeriodEnabled'] = value; } WFAD.updatePendingChanges(); }); $(window).on('wfOptionsReset', function() { $('#input-wafStatus').val($('#input-wafStatus').data('originalValue')).trigger('change'); $('#waf-learning-mode-grace-period .wf-option-checkbox').each(function() { var originalValue = $(this).data('originalValue'); $(this).toggleClass('wf-checked', !!originalValue); $('#waf-learning-mode-grace-period .wf-datetime').attr('disabled', !originalValue); }); $('.wf-datetime').each(function() { var el = $(this); if (el.attr('data-value')) { el.datetimepicker('setDate', new Date(el.attr('data-value') * 1000)); } else { el.val(''); } }) }); }); })(jQuery); </script> </p> <div id="waf-learning-mode-grace-period" class="wf-add-bottom" style="display: none;"><div class="waf-learning-mode wf-option-checkbox<?php try { echo $config->getConfig('learningModeGracePeriodEnabled') ? ' wf-checked' : ''; } catch (Exception $e) { /* Do nothing */ } ?>" data-original-value="<?php try { echo $config->getConfig('learningModeGracePeriodEnabled') ? 1 : 0; } catch (Exception $e) { echo 0; } ?>"><i class="wf-ion-ios-checkmark-empty" aria-hidden="true"></i></div><span> <?php esc_html_e('Automatically enable on', 'wordfence'); ?> </span><input type="text" name="learningModeGracePeriod" id="input-learningModeGracePeriod" class="wf-datetime wf-form-control" placeholder="Enabled until..." data-value="<?php try { echo esc_attr($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : ''); } catch (Exception $e) { /* Do nothing */ } ?>" data-original-value="<?php try { echo esc_attr($config->getConfig('learningModeGracePeriod') ? (int) $config->getConfig('learningModeGracePeriod') : ''); } catch (Exception $e) { /* Do nothing */ } ?>"<?php try { echo $config->getConfig('learningModeGracePeriodEnabled') ? '' : ' disabled'; } catch (Exception $e) { echo ' disabled'; } ?>></div> <?php endif; ?> </li> <li id="wf-option-protectionMode" class="wf-flex-vertical wf-flex-align-left"> <h3><?php esc_html_e('Protection Level', 'wordfence'); ?></h3> <?php if ($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_EXTENDED && !$firewall->isSubDirectoryInstallation()): ?> <p class="wf-no-top"><strong><?php esc_html_e('Extended Protection:', 'wordfence'); ?></strong> <?php esc_html_e('All PHP requests will be processed by the firewall prior to running.', 'wordfence'); ?></p> <p><?php echo wp_kses(sprintf(/* translators: Support URL. */ __('If you\'re moving to a new host or a new installation location, you may need to temporarily disable extended protection to avoid any file not found errors. Use this action to remove the configuration changes that enable extended protection mode or you can <a href="%s" target="_blank" rel="noopener noreferrer">remove them manually<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_FIREWALL_WAF_REMOVE_MANUALLY)), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'=>array()))); ?></p> <p class="wf-no-top"><a class="wf-btn wf-btn-default" href="#" id="wf-waf-uninstall" role="button"><?php esc_html_e('Remove Extended Protection', 'wordfence'); ?></a></p> <?php elseif ($firewall->isSubDirectoryInstallation()): ?> <p class="wf-no-top"><strong><?php esc_html_e('Existing WAF Installation Detected:', 'wordfence'); ?></strong> <?php esc_html_e('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please configure the firewall to run correctly on this site.', 'wordfence'); ?></p> <p><a class="wf-btn wf-btn-primary" href="#" id="wf-waf-install" role="button"><?php esc_html_e('Optimize the Wordfence Firewall', 'wordfence'); ?></a></p> <?php else: ?> <p class="wf-no-top"><strong><?php esc_html_e('Basic WordPress Protection:', 'wordfence'); ?></strong> <?php esc_html_e('The plugin will load as a regular plugin after WordPress has been loaded, and while it can block many malicious requests, some vulnerable plugins or WordPress itself may run vulnerable code before all plugins are loaded.', 'wordfence'); ?></p> <p><a class="wf-btn wf-btn-primary" href="#" id="wf-waf-install" role="button"><?php esc_html_e('Optimize the Wordfence Firewall', 'wordfence'); ?></a></p> <?php endif; ?> <script type="application/javascript"> (function($) { $(function() { var validateContinue = function() { var backupsAvailable = $('.wf-waf-backups:visible').data('backups'); var backupsDownloaded = $('#wf-waf-server-config').data('backups'); var matchCount = 0; backupsAvailable = backupsAvailable.sort(); backupsDownloaded = backupsDownloaded.sort(); for (var i = 0; i < backupsAvailable.length; i++) { for (var n = 0; n < backupsDownloaded.length; n++) { if (backupsAvailable[i] == backupsDownloaded[n]) { matchCount++; } } } $('#wf-waf-install-continue, #wf-waf-uninstall-continue').toggleClass('wf-disabled', matchCount != backupsAvailable.length); }; var installUninstallResponseHandler = function(action, res) { var modal = $('.wf-modal-title').closest('.wf-modal'); if (res.needsCredentials) { var replacement = $(res.html); modal.replaceWith(replacement); modal = replacement; var form = replacement.find('#request-filesystem-credentials-form').closest('form'); form.find('input[type="submit"]').attr('type', 'hidden'); form.on('submit', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.ajax(action, form.serialize(), function(res) { installUninstallResponseHandler(action, res); }); }); modal.find('#wf-waf-modal-continue').on('click', function(e) { e.preventDefault(); e.stopPropagation(); form.trigger('submit'); }); $.wfcolorbox.resize(); } else if (res.credentialsFailed || res.installationFailed || res.uninstallationFailed) { var replacement = $(res.html); modal.replaceWith(replacement); modal = replacement; modal.find('#wf-waf-modal-continue').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.colorboxClose(); }); $.wfcolorbox.resize(); var payload = {serverConfiguration: res.serverConfiguration, iniModified: 1}; if (res.credentials) { payload['credentials'] = res.credentials; payload['credentialsSignature'] = res.credentialsSignature; } $('.wf-waf-uninstall-try-again').on('click', function(e) { e.preventDefault(); e.stopPropagation(); $(this).text('Retrying'); payload['retryAttempted'] = 1; WFAD.ajax(action, payload, function(res) { installUninstallResponseHandler(action, res); }); }); } else if (res.uninstallationWaiting) { var replacement = $(res.html); modal.replaceWith(replacement); modal = replacement; modal.find('#wf-waf-modal-continue').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.colorboxClose(); }).addClass('wf-disabled'); var timeout = res.timeout; //In seconds setTimeout(function() { modal.find('#wf-waf-modal-continue').removeClass('wf-disabled'); var payload = {serverConfiguration: res.serverConfiguration, iniModified: 1}; if (res.credentials) { payload['credentials'] = res.credentials; payload['credentialsSignature'] = res.credentialsSignature; } WFAD.ajax(action, payload, function(res) { installUninstallResponseHandler(action, res); }); }, (timeout + 10) * 1000); $.wfcolorbox.resize(); } else if (res.ok) { var replacement = $(res.html); modal.replaceWith(replacement); modal = replacement; modal.find('#wf-waf-modal-continue').on('click', function(e) { e.preventDefault(); e.stopPropagation(); <?php if (array_key_exists('wf_deactivate', $_GET)): ?> window.location.href = <?php echo json_encode(wfUtils::wpAdminURL('plugins.php?wf_deactivate=true')); ?>; <?php else: ?> window.location.reload(true); <?php endif ?> }); $.wfcolorbox.resize(); } else { WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), <?php echo json_encode(__('Error During Setup', 'wordfence')) ?> , res.errorMsg); } }; var installUninstallHandler = function(html) { WFAD.colorboxHTML('800px', html, {overlayClose: false, closeButton: false, className: 'wf-modal', onComplete: function() { $('#wf-waf-server-config').data('backups', []); $('.wf-waf-backup-download').on('click', function(e) { var backupIndex = parseInt($(this).data('backupIndex')); var backupsAvailable = $(this).closest('.wf-waf-backups').data('backups'); var backupsDownloaded = $('#wf-waf-server-config').data('backups'); var found = false; for (var i = 0; i < backupsDownloaded.length; i++) { if (backupsDownloaded[i] == backupsAvailable[backupIndex]) { found = true; break; } } if (!found) { backupsDownloaded.push(backupsAvailable[backupIndex]); $('#wf-waf-server-config').data('backups', backupsDownloaded); validateContinue(); } }); $('#wf-waf-server-config').wfselect2({ minimumResultsForSearch: -1, width: WFAD.isSmallScreen ? '300px' : '500px' }); $('#wf-waf-include-prepend > li').each(function(index, element) { $(element).on('click', function(e) { e.preventDefault(); e.stopPropagation(); var control = $(this).closest('.wf-switch'); var value = $(this).data('optionValue'); control.find('li').each(function() { $(this).toggleClass('wf-active', value == $(this).data('optionValue')); }); }); }); var nginxNotice = $('.wf-nginx-waf-config'); var manualNotice = $('.wf-manual-waf-config'); $('#wf-waf-server-config').on('change', function() { var el = $(this); if (manualNotice.length) { if (el.val() == 'manual') { manualNotice.fadeIn(400, function () { $.wfcolorbox.resize(); }); } else { manualNotice.fadeOut(400, function () { $.wfcolorbox.resize(); }); } } var identifier = '.wf-waf-backups-' + el.val().replace(/[^a-z0-9\-]/i, ''); $('.wf-waf-backups').hide(); $(identifier).show(); if ($(identifier).find('.wf-waf-backup-file-list').children().length > 0) { $('.wf-waf-download-instructions').show(); } else { $('.wf-waf-download-instructions').hide(); } if (nginxNotice.length) { //Install only if (el.val() == 'nginx') { nginxNotice.fadeIn(400, function () { $.wfcolorbox.resize(); }); } else { nginxNotice.fadeOut(400, function () { $.wfcolorbox.resize(); }); } validateContinue(); return; } $.wfcolorbox.resize(); validateContinue(); }).triggerHandler('change'); $('#wf-waf-install-continue').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var serverConfiguration = $('#wf-waf-server-config').val(); var currentAutoPrepend = $('#wf-waf-include-prepend .wf-active').data('optionValue'); WFAD.ajax('wordfence_installAutoPrepend', {serverConfiguration: serverConfiguration, currentAutoPrepend: currentAutoPrepend}, function(res) { installUninstallResponseHandler('wordfence_installAutoPrepend', res); }); }); $('#wf-waf-uninstall-continue').on('click', function(e) { e.preventDefault(); e.stopPropagation(); if ($('.wf-manual-waf-config').is(':visible')) { WFAD.colorboxClose(); return; } var serverConfiguration = $('#wf-waf-server-config').val(); WFAD.ajax('wordfence_uninstallAutoPrepend', {serverConfiguration: serverConfiguration}, function(res) { installUninstallResponseHandler('wordfence_uninstallAutoPrepend', res); }); }); }}); }; $('#wf-waf-install').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var installer = $('#wafTmpl_install').tmpl(); var installerHTML = $("<div />").append(installer).html(); installUninstallHandler(installerHTML); }); $('#wf-waf-uninstall').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var uninstaller = $('#wafTmpl_uninstall').tmpl(); var uninstallerHTML = $("<div />").append(uninstaller).html(); installUninstallHandler(uninstallerHTML); }); if (window.location.hash) { var hashes = WFAD.parseHashes(); for (var i = 0; i < hashes.length; i++) { if (hashes[i] == 'configureAutoPrepend') { $('#wf-waf-install').trigger('click'); history.replaceState('', document.title, window.location.pathname + window.location.search); } else if (hashes[i] == 'removeAutoPrepend') { $('#wf-waf-uninstall').trigger('click'); history.replaceState('', document.title, window.location.pathname + window.location.search); } } } $(window).on('hashchange', function () { var hashes = WFAD.parseHashes(); for (var i = 0; i < hashes.length; i++) { if (hashes[i] == 'configureAutoPrepend') { $('#wf-waf-install').trigger('click'); history.replaceState('', document.title, window.location.pathname + window.location.search); } else if (hashes[i] == 'removeAutoPrepend') { $('#wf-waf-uninstall').trigger('click'); history.replaceState('', document.title, window.location.pathname + window.location.search); } } }); }); })(jQuery); </script> </li> <li id="wf-option-disableWAFBlacklistBlocking" class="wf-flex-vertical wf-flex-align-left"> <h3><?php esc_html_e('Real-Time IP Blocklist', 'wordfence'); ?></h3> <?php if ($firewall->ruleMode() == wfFirewall::RULE_MODE_COMMUNITY): ?> <p class="wf-no-top"><strong><?php esc_html_e('Premium Feature:', 'wordfence'); ?></strong> <?php esc_html_e('This feature blocks all traffic from IPs with a high volume of recent malicious activity using Wordfence\'s real-time blocklist.', 'wordfence'); ?></p> <p><a class="wf-btn wf-btn-primary wf-btn-callout-subtle" href="https://www.wordfence.com/gnl1blacklistUpgrade/wordfence-signup/#premium-order-form" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Upgrade to Premium', 'wordfence'); ?></a> <a class="wf-btn wf-btn-callout-subtle wf-btn-default" href="https://www.wordfence.com/gnl1blacklistLearn/wordfence-signup/" target="_blank" rel="noopener noreferrer"><?php esc_html_e('Learn More', 'wordfence'); ?><span class="screen-reader-text"> (<?php esc_html_e('opens in new tab', 'wordfence') ?>)</span></a></p> <?php elseif ($firewall->isSubDirectoryInstallation()): ?> <p class="wf-no-top"><?php echo wp_kses(sprintf(__('You are currently running the Wordfence Web Application Firewall from another WordPress installation. Please <a href="%s">click here</a> to configure the Firewall to run correctly on this site.', 'wordfence'), esc_attr(network_admin_url('admin.php?page=WordfenceWAF&subpage=waf_options#configureAutoPrepend'))), array('a'=>array('href'=>array()))); ?></p> <?php else: ?> <p class="wf-no-top"><?php esc_html_e('This feature blocks all traffic from IPs with a high volume of recent malicious activity using Wordfence\'s real-time blocklist.', 'wordfence'); ?></p> <div class="wf-option wf-option-switch wf-padding-add-bottom" data-option-name="disableWAFBlacklistBlocking" data-original-value="<?php try { echo $config->getConfig('disableWAFBlacklistBlocking') ? '1': '0'; } catch (Exception $e) { echo 0; } ?>"> <ul class="wf-switch" role="radiogroup"> <?php $states = array( array('value' => '1', 'label' => __('Disabled', 'wordfence')), array('value' => '0', 'label' => __('Enabled', 'wordfence')), ); foreach ($states as $s): $disableBlacklist = false; try { $disableBlacklist = !!$config->getConfig('disableWAFBlacklistBlocking'); } catch (Exception $e) { } ?> <li<?php if ($s['value'] == ($disableBlacklist ? '1': '0')) { echo ' class="wf-active"'; } ?> data-option-value="<?php echo esc_attr($s['value']); ?>" role="radio" aria-checked="<?php echo (($s['value'] == ($disableBlacklist ? '1': '0')) ? 'true' : 'false'); ?>" tabindex="0"><?php echo esc_html($s['label']); ?></li> <?php endforeach; ?> </ul> </div> <?php endif; ?> </li> </ul> </div> </div> </div> </div> <!-- end basic firewall options --> <?php if ($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_BASIC || ($firewall->protectionMode() == wfFirewall::PROTECTION_MODE_EXTENDED && $firewall->isSubDirectoryInstallation())) { echo wfView::create('waf/waf-install', array( ))->render(); } else { echo wfView::create('waf/waf-uninstall', array( ))->render(); } ?>PK m�}\zڙ�* �* pomo/translations.phpnu �[��� PK n�}\l�r��) �) -+ pomo/mo.phpnu �[��� PK p�}\���9� � BU pomo/entry.phpnu �[��� PK q�}\�3� � [f pomo/plural-forms.phpnu �[��� PK r�}\��O�H H �� pomo/streams.phpnu �[��� PK s�}\����"? "? � pomo/po.phpnu �[��� PK t�}\x=%� � m� wfWAFUserIPRange.phpnu �[��� PK v�}\�i y�N �N � wfWAFIPBlocksController.phpnu �[��� PK w�}\ob b �R .htaccessnu �[��� PK x�}\��sV V -T dummy.phpnu �[��� PK y�}\HE�$� $� �_ bootstrap.phpnu �[��� PK �~\�Zײ � � waf-uninstall-success.phpnu �[��� PK �~\ [��� � � waf-modal-wrapper.phpnu �[��� PK �~\�QQ/ Q/ V� options-group-whitelisted.phpnu �[��� PK �~\}:��O O �! waf-install-success.phpnu �[��� PK �~\��� � �% option-whitelist.phpnu �[��� PK �~\��ߘX( X( # �E options-group-advanced-firewall.phpnu �[��� PK �~\�k� � ln status-tooltip-learning-mode.phpnu �[��� PK �~\8�w�� � �q debug.phpnu �[��� PK �~\/7Íu u �� option-rules.phpnu �[��� PK �~\2"X�# �# G� waf-install.phpnu �[��� PK �~\�X�y y � option-rate-limit.phpnu �[��� PK �~\��� �� waf-install-manual.phpnu �[��� PK �~\z���� � � waf-uninstall.phpnu �[��� PK �~\�W�{C4 C4 �� options-group-rate-limiting.phpnu �[��� PK �~\���D� � � firewall-status.phpnu �[��� PK �~\TO�hk2 k2 �3 options-group-brute-force.phpnu �[��� PK �~\�j�l l lf options-group-basic-firewall.phpnu �[��� PK 8 ��