PluginProbe
The WP Remote WordPress Plugin / 4.79
The WP Remote WordPress Plugin v4.79
6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 5.73 All 53 releases
wpremote / protect / wp / lp / lp.php

lp.php in The WP Remote WordPress Plugin 4.79, at protect/wp/lp/lp.php

255 lines 7.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) exit;
4 if (!class_exists('BVWPLP')) :
5
6
7 class BVWPLP {
8 public $db;
9 public $settings;
10 private $ip;
11 private $time;
12 private $category;
13 private $username;
14 private $message;
15 public $config;
16 public $logger;
17 public $ipstore;
18 public static $requests_table = 'lp_requests';
19 public static $unblock_ip_transient = 'bvlp_unblock_ip';
20
21 #status
22 const LOGINFAILURE = 1;
23 const LOGINSUCCESS = 2;
24 const LOGINBLOCKED = 3;
25
26 #categories
27 const CAPTCHABLOCK = 1;
28 const TEMPBLOCK = 2;
29 const ALLBLOCKED = 3;
30 const UNBLOCKED = 4;
31 const BLACKLISTED = 5;
32 const BYPASSED = 6;
33 const ALLOWED = 7;
34 const PRIVATEIP = 8;
35
36 public function __construct($db, $settings, $ip, $ipstore, $confHash) {
37 $this->db = $db;
38 $this->settings = $settings;
39 $this->ip = $ip;
40 $this->config = new BVWPLPConfig($confHash);
41 $this->ipstore = $ipstore;
42 $this->logger = new BVLogger($db, BVWPLPConfig::$requests_table);
43 $this->time = strtotime(date("Y-m-d H:i:s"));
44 }
45
46 public function init() {
47 add_filter('authenticate', array($this, 'loginInit'), 30, 3);
48 add_action('wp_login', array($this, 'loginSuccess'));
49 add_action('wp_login_failed', array($this, 'loginFailed'));
50 }
51
52 public function setMessage($message) {
53 $this->message = $message;
54 }
55
56 public function setUserName($username) {
57 $this->username = $username;
58 }
59
60 public function setCategory($category) {
61 $this->category = $category;
62 }
63
64 public function getCaptchaLink() {
65 $account = WPRAccount::apiPublicAccount($this->settings);
66 $url = $account->authenticatedUrl('/captcha/solve');
67 $url .= "&adminurl=".base64_encode(get_admin_url());
68 return $url;
69 }
70
71 public function getUserName() {
72 return $this->username ? $this->username : '';
73 }
74
75 public function getMessage() {
76 return $this->message ? $this->message : '';
77 }
78
79 public function getCategory() {
80 return $this->category ? $this->category : BVWPLP::ALLOWED;
81 }
82
83 public function getCaptchaLimit() {
84 return $this->config->captchaLimit;
85 }
86
87 public function getFailedLoginGap() {
88 return $this->config->failedLoginGap;
89 }
90
91 public function getSuccessLoginGap() {
92 return $this->config->successLoginGap;
93 }
94
95 public function getAllBlockedGap() {
96 return $this->config->allBlockedGap;
97 }
98
99 public function getTempBlockLimit() {
100 return $this->config->tempBlockLimit;
101 }
102
103 public function getBlockAllLimit() {
104 return $this->config->blockAllLimit;
105 }
106
107 public function getAllowLoginsTransient() {
108 return $this->settings->getTransient('bvlp_allow_logins');
109 }
110
111 public function getBlockLoginsTransient() {
112 return $this->settings->getTransient('bvlp_block_logins');
113 }
114
115 public function terminateTemplate() {
116 $info = new WPRInfo($this->settings);
117 $brandname = $info->getBrandName().' Firewall';
118 $templates = array (
119 1 => "<p>Too many failed attempts, You are barred from logging into this site.</p><a href=".$this->getCaptchaLink()."
120 class='btn btn-default'>Click here</a> to unblock yourself.",
121 2 => "You cannot login to this site for 30 minutes because of too many failed login attempts.",
122 3 => "<p>Logins to this site are currently blocked.</p><a href=".$this->getCaptchaLink()."
123 class='btn btn-default'>Click here</a> to unblock yourself.",
124 5 => "Your IP is blacklisted."
125 );
126 return "
127 <div style='height: 98vh;'>
128 <div style='text-align: center; padding: 10% 0; font-family: Arial, Helvetica, sans-serif;'>
129 <div><p><img src=".plugins_url('/../../../img/icon.png', __FILE__)."><h2>Login Protection</h2><h3>powered by</h3><h2>"
130 .$brandname."</h2></p><div>
131 <p>" . $templates[$this->getCategory()]. "</p>
132 <p>Reference ID: " . WPRInfo::getRequestID() . "</p>
133 </div>
134 </div>";
135 }
136
137 public function isProtecting() {
138 return ($this->config->mode === BVWPLPConfig::PROTECT);
139 }
140
141 public function isActive() {
142 return ($this->config->mode !== BVWPLPConfig::DISABLED);
143 }
144
145 public function isBlacklistedIP() {
146 return $this->ipstore->isLPIPBlacklisted($this->ip);
147 }
148
149 public function isWhitelistedIP() {
150 return $this->ipstore->isLPIPWhitelisted($this->ip);
151 }
152
153 public function isUnBlockedIP() {
154 $transient_name = BVWPLP::$unblock_ip_transient.$this->ip;
155 $attempts = $this->settings->getTransient($transient_name);
156 if ($attempts && $attempts > 0) {
157 $this->settings->setTransient($transient_name, $attempts - 1, 600 * $attempts);
158 return true;
159 }
160 return false;
161 }
162
163 public function isLoginBlocked() {
164 if ($this->getAllowLoginsTransient() ||
165 ($this->getLoginCount(BVWPLP::LOGINFAILURE, null, $this->getAllBlockedGap()) < $this->getBlockAllLimit())) {
166 return false;
167 }
168 return true;
169 }
170
171 public function log($status) {
172 $data = array (
173 "ip" => $this->ip,
174 "status" => $status,
175 "time" => $this->time,
176 "category" => $this->getCategory(),
177 "username" => $this->getUserName(),
178 "request_id" => WPRInfo::getRequestID(),
179 "message" => $this->getMessage());
180 $this->logger->log($data);
181 }
182
183 public function terminateLogin() {
184 $this->setMessage('Login Blocked');
185 $this->log(BVWPLP::LOGINBLOCKED);
186 if ($this->isProtecting()) {
187 header("Cache-Control: no-cache, no-store, must-revalidate");
188 header("Pragma: no-cache");
189 header("Expires: 0");
190 header('HTTP/1.0 403 Forbidden');
191 die($this->terminateTemplate());
192 exit;
193 }
194 }
195
196 public function loginInit($user, $username = '', $password = '') {
197 if ($this->isUnBlockedIP()) {
198 $this->setCategory(BVWPLP::UNBLOCKED);
199 } else {
200 $failed_attempts = $this->getLoginCount(BVWPLP::LOGINFAILURE, $this->ip, $this->getFailedLoginGap());
201 if ($this->isWhitelistedIP()) {
202 $this->setCategory(BVWPLP::BYPASSED);
203 } else if (BVProtectBase::isPrivateIP($this->ip)) {
204 $this->setCategory(BVWPLP::PRIVATEIP);
205 } else if ($this->isBlacklistedIP()) {
206 $this->setCategory(BVWPLP::BLACKLISTED);
207 $this->terminateLogin();
208 } else if ($this->isKnownLogin()) {
209 $this->setCategory(BVWPLP::BYPASSED);
210 } else if ($this->isLoginBlocked()) {
211 $this->setCategory(BVWPLP::ALLBLOCKED);
212 $this->terminateLogin();
213 } else if ($failed_attempts >= $this->getTempBlockLimit()) {
214 $this->setCategory(BVWPLP::TEMPBLOCK);
215 $this->terminateLogin();
216 } else if ($failed_attempts >= $this->getCaptchaLimit()) {
217 $this->setCategory(BVWPLP::CAPTCHABLOCK);
218 $this->terminateLogin();
219 }
220 }
221 if (!empty($user) && !empty($password) && is_wp_error($user)) {
222 $this->setMessage($user->get_error_code());
223 }
224 return $user;
225 }
226
227 public function loginFailed($username) {
228 $this->setUserName($username);
229 $this->log(BVWPLP::LOGINFAILURE);
230 }
231
232 public function loginSuccess($username) {
233 $this->setUserName($username);
234 $this->setMessage('Login Success');
235 $this->log(BVWPLP::LOGINSUCCESS);
236 }
237
238 public function isKnownLogin() {
239 return $this->getLoginCount(BVWPLP::LOGINSUCCESS, $this->ip, $this->getSuccessLoginGap()) > 0;
240 }
241
242 public function getLoginCount($status, $ip = null, $gap = 1800) {
243 $db = $this->db;
244 $table = $db->getBVTable(BVWPLP::$requests_table);
245 $query = $db->prepare("SELECT COUNT(*) as count from `$table` WHERE status=%d && time > %d", array($status, ($this->time - $gap)));
246 if ($ip) {
247 $query .= $db->prepare(" && ip=%s", $ip);
248 }
249 $rows = $db->getResult($query);
250 if (!$rows)
251 return 0;
252 return intval($rows[0]['count']);
253 }
254 }
255 endif;