ip = $request->getIP();
$this->brand_name = $brand_name;
$this->ipstore = new WPRProtectIpstore_V644();
$this->logger = new WPRProtectLogger_V644(WPRProtectLP_V644::TABLE_NAME);
$this->time = strtotime(gmdate("Y-m-d H:i:s"));
if (is_array($config)) {
if (array_key_exists('mode', $config) && is_int($config['mode'])) {
$this->mode = $config['mode'];
}
if (array_key_exists('captchalimit', $config) && is_int($config['captchalimit'])) {
$this->captcha_limit = $config['captchalimit'];
}
if (array_key_exists('tempblocklimit', $config) && is_int($config['tempblocklimit'])) {
$this->temp_block_limit = $config['tempblocklimit'];
}
if (array_key_exists('blockalllimit', $config) && is_int($config['blockalllimit'])) {
$this->block_all_limit = $config['blockalllimit'];
}
if (array_key_exists('failedlogingap', $config) && is_int($config['failedlogingap'])) {
$this->failed_login_gap = $config['failedlogingap'];
}
if (array_key_exists('successlogingap', $config) && is_int($config['successlogingap'])) {
$this->success_login_gap = $config['successlogingap'];
}
if (array_key_exists('allblockedgap', $config) && is_int($config['allblockedgap'])) {
$this->all_blocked_gap = $config['allblockedgap'];
}
}
}
public static function getInstance($request, $config, $brand_name) {
if (!isset(self::$instance)) {
self::$instance = new self($request, $config, $brand_name);
}
return self::$instance;
}
public static function uninstall() {
WPRProtect_V644::$db->dropBVTable(WPRProtectLP_V644::TABLE_NAME);
}
public function init() {
if ($this->isActive()) {
add_filter('authenticate', array($this, 'loginInit'), 30, 3);
add_action('wp_login', array($this, 'loginSuccess'));
add_action('wp_login_failed', array($this, 'loginFailed'));
}
}
private function getCaptchaLink() {
$account = WPRAccount::apiPublicAccount(WPRProtect_V644::$settings);
$url = $account->authenticatedUrl('/captcha/solve');
$url .= "&adminurl=".base64_encode(get_admin_url());
return $url;
}
private function getAllowLoginsTransient() {
return WPRProtect_V644::$settings->getTransient('bvlp_allow_logins');
}
private function getBlockLoginsTransient() {
return WPRProtect_V644::$settings->getTransient('bvlp_block_logins');
}
private function terminateTemplate() {
$templates = array (
1 => "
Too many failed attempts, You are barred from logging into this site.
" .
"Click here" .
" to unblock yourself.",
2 => "You cannot login to this site for 30 minutes because of too many failed login attempts.",
3 => "Logins to this site are currently blocked.
Click here to unblock yourself.",
5 => "Your IP is blacklisted."
);
return "
 . )
Login Protection
powered by
"
. esc_html($this->brand_name) . " Firewall
" . $templates[$this->category] . "
Reference ID: " . esc_html(WPRInfo::getRequestID()) . "
";
}
private function isProtecting() {
return $this->mode === WPRProtectLP_V644::MODE_PROTECT;
}
private function isActive() {
return $this->mode !== WPRProtectLP_V644::MODE_DISABLED;
}
private function isBlacklistedIP() {
return $this->ipstore->isLPIPBlacklisted($this->ip);
}
private function isWhitelistedIP() {
return $this->ipstore->isLPIPWhitelisted($this->ip);
}
private function isUnBlockedIP() {
$transient_name = WPRProtectLP_V644::UNBLOCK_IP_TRANSIENT_PREFIX . $this->ip;
$attempts = WPRProtect_V644::$settings->getTransient($transient_name);
if ($attempts && $attempts > 0) {
WPRProtect_V644::$settings->setTransient($transient_name, $attempts - 1, 600 * $attempts);
return true;
}
return false;
}
private function isLoginBlocked() {
if ($this->getAllowLoginsTransient() ||
($this->getLoginCount(WPRProtectLP_V644::LOGIN_STATUS_FAILURE, null, $this->all_blocked_gap) < $this->block_all_limit)) {
return false;
}
return true;
}
private function log($status) {
$data = array (
"ip" => $this->ip,
"status" => $status,
"time" => $this->time,
"category" => $this->category,
"username" => $this->username,
"request_id" => WPRInfo::getRequestID(),
"message" => $this->message
);
$this->logger->log($data);
}
private function terminateLogin() {
$this->message = 'Login Blocked';
$this->log(WPRProtectLP_V644::LOGIN_STATUS_BLOCKED);
if ($this->isProtecting()) {
header("Cache-Control: no-cache, no-store, must-revalidate");
header("Pragma: no-cache");
header("Expires: 0");
header('HTTP/1.0 403 Forbidden');
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Already Escaped
die($this->terminateTemplate());
exit;
}
}
public function loginInit($user, $username = '', $password = '') {
if ($this->isUnBlockedIP()) {
$this->category = WPRProtectLP_V644::CATEGORY_UNBLOCKED;
} else {
$failed_attempts = $this->getLoginCount(WPRProtectLP_V644::LOGIN_STATUS_FAILURE,
$this->ip, $this->failed_login_gap);
if ($this->isWhitelistedIP()) {
$this->category = WPRProtectLP_V644::CATEGORY_BYPASSED;
} elseif (WPRProtectUtils_V644::isPrivateIP($this->ip)) {
$this->category = WPRProtectLP_V644::CATEGORY_PRIVATEIP;
} elseif ($this->isBlacklistedIP()) {
$this->category = WPRProtectLP_V644::CATEGORY_BLACKLISTED;
$this->terminateLogin();
} elseif ($this->isKnownLogin()) {
$this->category = WPRProtectLP_V644::CATEGORY_BYPASSED;
} elseif ($this->isLoginBlocked()) {
$this->category = WPRProtectLP_V644::CATEGORY_ALL_BLOCKED;
$this->terminateLogin();
} elseif ($failed_attempts >= $this->temp_block_limit) {
$this->category = WPRProtectLP_V644::CATEGORY_TEMP_BLOCK;
$this->terminateLogin();
} elseif ($failed_attempts >= $this->captcha_limit) {
$this->category = WPRProtectLP_V644::CATEGORY_CAPTCHA_BLOCK;
$this->terminateLogin();
}
}
if (!empty($user) && !empty($password) && is_wp_error($user)) {
$this->message = $user->get_error_code();
}
return $user;
}
public function loginFailed($username) {
$this->username = $username;
$this->log(WPRProtectLP_V644::LOGIN_STATUS_FAILURE);
}
public function loginSuccess($username) {
$this->username = $username;
$this->message = 'Login Success';
$this->log(WPRProtectLP_V644::LOGIN_STATUS_SUCCESS);
}
private function isKnownLogin() {
return $this->getLoginCount(WPRProtectLP_V644::LOGIN_STATUS_SUCCESS,
$this->ip, $this->success_login_gap) > 0;
}
private function getLoginCount($status, $ip, $gap) {
$table = WPRProtect_V644::$db->getBVTable(WPRProtectLP_V644::TABLE_NAME);
$query_str = "SELECT COUNT(*) as count from `$table` WHERE status=%d && time > %d";
$query_args = array($status, ($this->time - $gap));
$query = WPRProtect_V644::$db->prepare($query_str, $query_args);
if ($ip) {
$query .= WPRProtect_V644::$db->prepare(" && ip=%s", $ip);
}
$rows = WPRProtect_V644::$db->getResult($query);
if (!$rows) {
return 0;
}
return intval($rows[0]['count']);
}
}
endif;