' . $this->_messageHTML . '
' . sprintf(__('Dismiss', 'wordfence'), esc_attr($this->_id)) . '
';
}
}PK ! >մN N , login-security/classes/model/tokenbucket.phpnu [ _identifier = $identifier;
$this->_bucketSize = $bucketSize;
$this->_tokensPerSecond = $tokensPerSecond;
$this->_backing = $backing;
if ($backing == self::BACKING_REDIS) {
$this->_redis = new \Redis();
$this->_redis->pconnect('127.0.0.1');
}
}
/**
* Attempts to acquire a lock for the bucket.
*
* @param int $timeout
* @return bool Whether or not the lock was acquired.
*/
private function _lock($timeout = 30) {
if ($this->_backing == self::BACKING_WP_OPTIONS) {
$start = microtime(true);
while (!$this->_wp_options_create_lock($this->_identifier)) {
if (microtime(true) - $start > $timeout) {
return false;
}
usleep(5000); // 5 ms
}
return true;
}
else if ($this->_backing == self::BACKING_REDIS) {
if ($this->_redis === false) {
return false;
}
$start = microtime(true);
while (!$this->_redis->setnx('lock:' . $this->_identifier, '1')) {
if (microtime(true) - $start > $timeout) {
return false;
}
usleep(5000); // 5 ms
}
$this->_redis->expire('lock:' . $this->_identifier, 30);
return true;
}
return false;
}
private function _unlock() {
if ($this->_backing == self::BACKING_WP_OPTIONS) {
$this->_wp_options_release_lock($this->_identifier);
}
else if ($this->_backing == self::BACKING_REDIS) {
if ($this->_redis === false) {
return;
}
$this->_redis->del('lock:' . $this->_identifier);
}
}
private function _wp_options_create_lock($name, $timeout = null) { //Our own version of WP_Upgrader::create_lock
global $wpdb;
if (!$timeout) {
$timeout = 3600;
}
$lock_option = 'wfls_' . $name . '.lock';
$lock_result = $wpdb->query($wpdb->prepare("INSERT IGNORE INTO `{$wpdb->options}` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, 'no')", $lock_option, time()));
if (!$lock_result) {
$lock_result = get_option($lock_option);
if (!$lock_result) {
return false;
}
if ($lock_result > (time() - $timeout)) {
return false;
}
$this->_wp_options_release_lock($name);
return $this->_wp_options_create_lock($name, $timeout);
}
return true;
}
private function _wp_options_release_lock($name) {
return delete_option('wfls_' . $name . '.lock');
}
/**
* Atomically checks the available token count, creating the initial record if needed, and updates the available token count if the requested number of tokens is available.
*
* @param int $tokenCount
* @return bool Whether or not there were enough tokens to satisfy the request.
*/
public function consume($tokenCount = 1) {
if (!$this->_lock()) { return false; }
if ($this->_backing == self::BACKING_WP_OPTIONS) {
$record = get_transient('wflsbucket:' . $this->_identifier);
}
else if ($this->_backing == self::BACKING_REDIS) {
$record = $this->_redis->get('bucket:' . $this->_identifier);
}
else {
$this->_unlock();
return false;
}
if ($record === false) {
if ($tokenCount > $this->_bucketSize) {
$this->_unlock();
return false;
}
$this->_bootstrap($this->_bucketSize - $tokenCount);
$this->_unlock();
return true;
}
$tokens = min($this->_secondsToTokens(microtime(true) - (float) $record), $this->_bucketSize);
if ($tokenCount > $tokens) {
$this->_unlock();
return false;
}
if ($this->_backing == self::BACKING_WP_OPTIONS) {
set_transient('wflsbucket:' . $this->_identifier, (string) (microtime(true) - $this->_tokensToSeconds($tokens - $tokenCount)), ceil($this->_tokensToSeconds($this->_bucketSize)));
}
else if ($this->_backing == self::BACKING_REDIS) {
$this->_redis->set('bucket:' . $this->_identifier, (string) (microtime(true) - $this->_tokensToSeconds($tokens - $tokenCount)));
}
$this->_unlock();
return true;
}
public function reset() {
if (!$this->_lock()) { return false; }
if ($this->_backing == self::BACKING_WP_OPTIONS) {
delete_transient('wflsbucket:' . $this->_identifier);
}
else if ($this->_backing == self::BACKING_REDIS) {
$this->_redis->del('bucket:' . $this->_identifier);
}
$this->_unlock();
}
/**
* Creates an initial record with the given number of tokens.
*
* @param int $initialTokens
*/
protected function _bootstrap($initialTokens) {
$microtime = microtime(true) - $this->_tokensToSeconds($initialTokens);
if ($this->_backing == self::BACKING_WP_OPTIONS) {
set_transient('wflsbucket:' . $this->_identifier, (string) $microtime, ceil($this->_tokensToSeconds($this->_bucketSize)));
}
else if ($this->_backing == self::BACKING_REDIS) {
$this->_redis->set('bucket:' . $this->_identifier, (string) $microtime);
}
}
protected function _tokensToSeconds($tokens) {
return $tokens / $this->_tokensPerSecond;
}
protected function _secondsToTokens($seconds) {
return (int) $seconds * $this->_tokensPerSecond;
}
}
PK ! N ' login-security/classes/model/script.phpnu [ registered) {
wp_enqueue_script($this->handle);
}
else {
wp_enqueue_script($this->handle, $this->source, $this->dependencies, $this->version);
}
if ($this->translationObjectName && !empty($this->translations)) {
wp_localize_script($this->handle, $this->translationObjectName, $this->translations);
}
}
public function isEnqueued() {
return wp_script_is($this->handle);
}
public function renderInline() {
if (empty($this->source))
return;
?>
handle, $this->source, $this->dependencies, $this->version);
return parent::register();
}
public function withTranslation($placeholder, $translation) {
$this->translations[$placeholder] = $translation;
return $this;
}
public function withTranslations($translations) {
$this->translations = $translations;
return $this;
}
public function setTranslationObjectName($name) {
$this->translationObjectName = $name;
return $this;
}
}PK ! ϻ
6 login-security/classes/model/2fainitializationdata.phpnu [ user = $user;
$this->raw_secret = Model_Crypto::random_bytes(20);
}
public function get_user() {
return $this->user;
}
public function get_raw_secret() {
return $this->raw_secret;
}
public function get_base32_secret() {
if ($this->base32_secret === null)
$this->base32_secret = Utility_BaseConversion::base32_encode($this->raw_secret);
return $this->base32_secret;
}
private function generate_otp_url() {
return "otpauth://totp/" . rawurlencode(preg_replace('~^https?://(?:www\.)?~i', '', home_url()) . ':' . $this->user->user_login) . '?secret=' . $this->get_base32_secret() . '&algorithm=SHA1&digits=6&period=30&issuer=' . rawurlencode(preg_replace('~^https?://(?:www\.)?~i', '', home_url()));
}
public function get_otp_url() {
if ($this->otp_url === null)
$this->otp_url = $this->generate_otp_url();
return $this->otp_url;
}
public function get_recovery_codes() {
if ($this->recovery_codes === null)
$this->recovery_codes = Controller_Users::shared()->regenerate_recovery_codes();
return $this->recovery_codes;
}
}PK ! ) login-security/classes/model/settings.phpnu [ path = WORDFENCE_LS_PATH . 'views';
$this->view = $view;
$this->data = $data;
}
/**
* @return string
* @throws ViewNotFoundException
*/
public function render() {
$view = preg_replace('/\.{2,}/', '.', $this->view);
$path = $this->path . '/' . $view . $this->file_extension;
if (!file_exists($path)) {
throw new ViewNotFoundException('The view ' . $path . ' does not exist or is not readable.');
}
extract($this->data, EXTR_SKIP);
ob_start();
/** @noinspection PhpIncludeInspection */
include $path;
return ob_get_clean();
}
/**
* @return string
*/
public function __toString() {
try {
return $this->render();
}
catch (ViewNotFoundException $e) {
return defined('WP_DEBUG') && WP_DEBUG ? $e->getMessage() : 'The view could not be loaded.';
}
}
/**
* @param $data
* @return $this
*/
public function addData($data) {
$this->data = array_merge($data, $this->data);
return $this;
}
/**
* @return array
*/
public function getData() {
return $this->data;
}
/**
* @param array $data
* @return $this
*/
public function setData($data) {
$this->data = $data;
return $this;
}
/**
* @return string
*/
public function getView() {
return $this->view;
}
/**
* @param string $view
* @return $this
*/
public function setView($view) {
$this->view = $view;
return $this;
}
/**
* Prevent POP
*/
public function __wakeup() {
$this->path = WORDFENCE_LS_PATH . 'views';
$this->view = null;
$this->data = array();
$this->file_extension = '.php';
}
}
class ViewNotFoundException extends \Exception { }
PK ! pf # login-security/classes/model/ip.phpnu [ $group) {
if ($group == '0000' && !$done_collapse) {
if ($in_collapse) {
$groups[$index] = '';
continue;
}
$groups[$index] = ':';
$in_collapse = true;
continue;
}
if ($in_collapse) {
$done_collapse = true;
}
$groups[$index] = ltrim($groups[$index], '0');
if (strlen($groups[$index]) === 0) {
$groups[$index] = '0';
}
}
$ip = join(':', array_filter($groups, 'strlen'));
$ip = str_replace(':::', '::', $ip);
return $ip == ':' ? '::' : $ip;
}
return false;
}
/**
* Returns the packed binary representation of an IP address from the human readable version.
*
* @param string $ip
* @return string
*/
public static function inet_pton($ip) {
if (self::has_ipv6()) {
$pton = @inet_pton($ip);
if ($pton === false) {
return false;
}
}
else {
if (preg_match('/^(?:\d{1,3}(?:\.|$)){4}/', $ip)) { // IPv4
$octets = explode('.', $ip);
$pton = chr($octets[0]) . chr($octets[1]) . chr($octets[2]) . chr($octets[3]);
}
else if (preg_match('/^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/i', $ip)) { // IPv6
if ($ip === '::') {
$pton = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
}
else {
$colon_count = substr_count($ip, ':');
$dbl_colon_pos = strpos($ip, '::');
if ($dbl_colon_pos !== false) {
$ip = str_replace('::', str_repeat(':0000', (($dbl_colon_pos === 0 || $dbl_colon_pos === strlen($ip) - 2) ? 9 : 8) - $colon_count) . ':', $ip);
$ip = trim($ip, ':');
}
$ip_groups = explode(':', $ip);
$ipv6_bin = '';
foreach ($ip_groups as $ip_group) {
$ipv6_bin .= pack('H*', str_pad($ip_group, 4, '0', STR_PAD_LEFT));
}
if (Model_Crypto::strlen($ipv6_bin) == 16) {
$pton = $ipv6_bin;
}
else {
return false;
}
}
}
else if (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, $matches)) { // IPv4 mapped IPv6
$octets = explode('.', $matches[1]);
$pton = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff" . chr($octets[0]) . chr($octets[1]) . chr($octets[2]) . chr($octets[3]);
}
else {
return false;
}
}
$pton = str_pad($pton, 16, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00", STR_PAD_LEFT);
return $pton;
}
/**
* Verify PHP was compiled with IPv6 support.
*
* Some hosts appear to not have inet_ntop, and others appear to have inet_ntop but are unable to process IPv6 addresses.
*
* @return bool
*/
public static function has_ipv6() {
return defined('AF_INET6');
}
/**
* Expands a compressed printable representation of an IPv6 address.
*
* @param string $ip
* @return string
*/
public static function expand_ipv6_address($ip) {
$hex = bin2hex(self::inet_pton($ip));
$ip = substr(preg_replace("/([a-f0-9]{4})/i", "$1:", $hex), 0, -1);
return $ip;
}
/**
* Returns whether or not the IP is a valid format.
*
* @param string $ip
* @return bool
*/
public static function is_valid_ip($ip) {
return filter_var($ip, FILTER_VALIDATE_IP) !== false;
}
/**
* Returns whether or not the range is a valid CIDR range.
*
* @param string $range
* @return bool
*/
public static function is_valid_cidr_range($range) {
$components = explode('/', $range);
if (count($components) != 2) { return false; }
list($ip, $prefix) = $components;
if (!self::is_valid_ip($ip)) { 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;
}
/**
* Returns whether or not the IP is in the IPv6-mapped-IPv4 format.
*
* @param string $ip
* @return bool
*/
public static function is_ipv6_mapped_ipv4($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;
}
}PK ! H5+ + &