Version Description
- Added Support For Multi Table Callbacks
- Added Firewall Rule Evaluator
- Added Activity Logs feature
- Minor Improvements
Download this release
Release Info
Developer | ritesh.soni36 |
Plugin | WordPress Backup & Security Plugin – BlogVault |
Version | 4.54 |
Comparing to | |
See all releases |
Code changes from version 4.36 to 4.54
- account.php +63 -2
- blogvault.php +14 -3
- callback/handler.php +4 -0
- callback/wings/account.php +3 -7
- callback/wings/actlog.php +60 -0
- callback/wings/db.php +83 -5
- callback/wings/fs.php +2 -4
- callback/wings/fs_write.php +3 -3
- callback/wings/info.php +2 -0
- callback/wings/misc.php +12 -3
- callback/wings/protect.php +11 -0
- callback/wings/watch.php +10 -0
- info.php +25 -4
- protect/fw/config.php +9 -4
- protect/fw/fw.php +86 -6
- protect/fw/request.php +55 -24
- protect/fw/rule_evaluator.php +375 -0
- protect/prepend/protect.php +5 -2
- protect/wp/lp/lp.php +4 -2
- protect/wp/protect.php +88 -3
- readme.txt +7 -1
- wp_actions.php +1 -1
- wp_actlog.php +263 -0
- wp_site_info.php +6 -0
account.php
CHANGED
@@ -84,6 +84,39 @@ if (!class_exists('BVAccount')) :
|
|
84 |
return $accountsByPlugname;
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
public static function isConfigured($settings) {
|
88 |
$accounts = self::accountsByPlugname($settings);
|
89 |
return (sizeof($accounts) >= 1);
|
@@ -155,16 +188,22 @@ if (!class_exists('BVAccount')) :
|
|
155 |
$this->settings->updateOption('bvLastRecvTime', $time);
|
156 |
return 1;
|
157 |
}
|
158 |
-
|
159 |
public function updateInfo($info) {
|
160 |
$accounts = self::allAccounts($this->settings);
|
161 |
-
$plugname =
|
|
|
162 |
$pubkey = $info['pubkey'];
|
163 |
if (!array_key_exists($pubkey, $accounts)) {
|
164 |
$accounts[$pubkey] = array();
|
165 |
}
|
|
|
|
|
|
|
|
|
166 |
$accounts[$pubkey]['lastbackuptime'] = time();
|
167 |
$accounts[$pubkey][$plugname] = true;
|
|
|
168 |
$accounts[$pubkey]['url'] = $info['url'];
|
169 |
$accounts[$pubkey]['email'] = $info['email'];
|
170 |
self::update($this->settings, $accounts);
|
@@ -180,6 +219,28 @@ if (!class_exists('BVAccount')) :
|
|
180 |
return false;
|
181 |
}
|
182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
public static function exists($settings, $pubkey) {
|
184 |
$accounts = self::allAccounts($settings);
|
185 |
return array_key_exists($pubkey, $accounts);
|
84 |
return $accountsByPlugname;
|
85 |
}
|
86 |
|
87 |
+
public static function accountsByType($settings, $account_type) {
|
88 |
+
$accounts = self::allAccounts($settings);
|
89 |
+
$accounts_by_type = array();
|
90 |
+
foreach ($accounts as $pubkey => $value) {
|
91 |
+
if (array_key_exists('account_type', $value) && $value['account_type'] === $account_type) {
|
92 |
+
$accounts_by_type[$pubkey] = $value;
|
93 |
+
}
|
94 |
+
}
|
95 |
+
return $accounts_by_type;
|
96 |
+
}
|
97 |
+
|
98 |
+
public static function accountsByGid($settings, $account_gid) {
|
99 |
+
$accounts = self::allAccounts($settings);
|
100 |
+
$accounts_by_gid = array();
|
101 |
+
foreach ($accounts as $pubkey => $value) {
|
102 |
+
if (array_key_exists('account_gid', $value) && $value['account_gid'] === $account_gid) {
|
103 |
+
$accounts_by_gid[$pubkey] = $value;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
return $accounts_by_gid;
|
107 |
+
}
|
108 |
+
|
109 |
+
public static function accountsByPattern($settings, $search_key, $search_pattern) {
|
110 |
+
$accounts = self::allAccounts($settings);
|
111 |
+
$accounts_by_pattern = array();
|
112 |
+
foreach ($accounts as $pubkey => $value) {
|
113 |
+
if (array_key_exists($search_key, $value) && preg_match($search_pattern, $value[$search_key]) == 1) {
|
114 |
+
$accounts_by_pattern[$pubkey] = $value;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
return $accounts_by_pattern;
|
118 |
+
}
|
119 |
+
|
120 |
public static function isConfigured($settings) {
|
121 |
$accounts = self::accountsByPlugname($settings);
|
122 |
return (sizeof($accounts) >= 1);
|
188 |
$this->settings->updateOption('bvLastRecvTime', $time);
|
189 |
return 1;
|
190 |
}
|
191 |
+
|
192 |
public function updateInfo($info) {
|
193 |
$accounts = self::allAccounts($this->settings);
|
194 |
+
$plugname = $info["plugname"];
|
195 |
+
$account_type = $info["account_type"];
|
196 |
$pubkey = $info['pubkey'];
|
197 |
if (!array_key_exists($pubkey, $accounts)) {
|
198 |
$accounts[$pubkey] = array();
|
199 |
}
|
200 |
+
if (array_key_exists('secret', $info)) {
|
201 |
+
$accounts[$pubkey]['secret'] = $info['secret'];
|
202 |
+
}
|
203 |
+
$accounts[$pubkey]['account_gid'] = $info['account_gid'];
|
204 |
$accounts[$pubkey]['lastbackuptime'] = time();
|
205 |
$accounts[$pubkey][$plugname] = true;
|
206 |
+
$accounts[$pubkey]['account_type'] = $account_type;
|
207 |
$accounts[$pubkey]['url'] = $info['url'];
|
208 |
$accounts[$pubkey]['email'] = $info['email'];
|
209 |
self::update($this->settings, $accounts);
|
219 |
return false;
|
220 |
}
|
221 |
|
222 |
+
public static function removeByAccountType($settings, $account_type) {
|
223 |
+
$accounts = BVAccount::accountsByType($settings, $account_type);
|
224 |
+
if (sizeof($accounts) >= 1) {
|
225 |
+
foreach ($accounts as $pubkey => $value) {
|
226 |
+
BVAccount::remove($settings, $pubkey);
|
227 |
+
}
|
228 |
+
return true;
|
229 |
+
}
|
230 |
+
return false;
|
231 |
+
}
|
232 |
+
|
233 |
+
public static function removeByAccountGid($settings, $account_gid) {
|
234 |
+
$accounts = BVAccount::accountsByGid($settings, $account_gid);
|
235 |
+
if (sizeof($accounts) >= 1) {
|
236 |
+
foreach ($accounts as $pubkey => $value) {
|
237 |
+
BVAccount::remove($settings, $pubkey);
|
238 |
+
}
|
239 |
+
return true;
|
240 |
+
}
|
241 |
+
return false;
|
242 |
+
}
|
243 |
+
|
244 |
public static function exists($settings, $pubkey) {
|
245 |
$accounts = self::allAccounts($settings);
|
246 |
return array_key_exists($pubkey, $accounts);
|
blogvault.php
CHANGED
@@ -5,7 +5,7 @@ Plugin URI: https://blogvault.net
|
|
5 |
Description: Easiest way to backup & secure your WordPress site
|
6 |
Author: Backup by BlogVault
|
7 |
Author URI: https://blogvault.net
|
8 |
-
Version: 4.
|
9 |
Network: True
|
10 |
*/
|
11 |
|
@@ -69,6 +69,7 @@ if (is_admin()) {
|
|
69 |
add_action('admin_head', array($wpadmin, 'removeAdminNotices'), 3);
|
70 |
add_action('admin_notices', array($wpadmin, 'activateWarning'));
|
71 |
##ADMINENQUEUESCRIPTS##
|
|
|
72 |
}
|
73 |
|
74 |
|
@@ -130,10 +131,13 @@ if ((array_key_exists('bvplugname', $_REQUEST)) && ($_REQUEST['bvplugname'] == "
|
|
130 |
$response->terminate($resp);
|
131 |
}
|
132 |
} else {
|
133 |
-
if ($
|
134 |
require_once dirname( __FILE__ ) . '/protect/wp/protect.php';
|
135 |
$bvprotect = new BVProtect($bvdb, $bvsettings);
|
136 |
-
$bvprotect->
|
|
|
|
|
|
|
137 |
}
|
138 |
|
139 |
if ($bvinfo->isDynSyncModuleEnabled()) {
|
@@ -142,6 +146,13 @@ if ((array_key_exists('bvplugname', $_REQUEST)) && ($_REQUEST['bvplugname'] == "
|
|
142 |
$dynsync->init();
|
143 |
}
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
$bv_site_settings = $bvsettings->getOption('bv_site_settings');
|
146 |
if (isset($bv_site_settings)) {
|
147 |
if (isset($bv_site_settings['wp_auto_updates'])) {
|
5 |
Description: Easiest way to backup & secure your WordPress site
|
6 |
Author: Backup by BlogVault
|
7 |
Author URI: https://blogvault.net
|
8 |
+
Version: 4.54
|
9 |
Network: True
|
10 |
*/
|
11 |
|
69 |
add_action('admin_head', array($wpadmin, 'removeAdminNotices'), 3);
|
70 |
add_action('admin_notices', array($wpadmin, 'activateWarning'));
|
71 |
##ADMINENQUEUESCRIPTS##
|
72 |
+
##REMOVEDEACTIVATIONLINK##
|
73 |
}
|
74 |
|
75 |
|
131 |
$response->terminate($resp);
|
132 |
}
|
133 |
} else {
|
134 |
+
if ($bvsettings->getOption('bvptplug') === $bvinfo->plugname) {
|
135 |
require_once dirname( __FILE__ ) . '/protect/wp/protect.php';
|
136 |
$bvprotect = new BVProtect($bvdb, $bvsettings);
|
137 |
+
$bvprotect->init();
|
138 |
+
if ($bvinfo->isActivePlugin() && !(defined( 'WP_CLI' ) && WP_CLI)) {
|
139 |
+
$bvprotect->run();
|
140 |
+
}
|
141 |
}
|
142 |
|
143 |
if ($bvinfo->isDynSyncModuleEnabled()) {
|
146 |
$dynsync->init();
|
147 |
}
|
148 |
|
149 |
+
if ($bvinfo->isServiceActive('activity_log')) {
|
150 |
+
require_once dirname( __FILE__ ) . '/wp_actlog.php';
|
151 |
+
$bvconfig = $bvinfo->config;
|
152 |
+
$actlog = new BVWPActLog($bvdb, $bvsettings, $bvinfo, $bvconfig['activity_log']);
|
153 |
+
$actlog->init();
|
154 |
+
}
|
155 |
+
|
156 |
$bv_site_settings = $bvsettings->getOption('bv_site_settings');
|
157 |
if (isset($bv_site_settings)) {
|
158 |
if (isset($bv_site_settings['wp_auto_updates'])) {
|
callback/handler.php
CHANGED
@@ -88,6 +88,10 @@ if (!class_exists('BVCallbackHandler')) :
|
|
88 |
require_once dirname( __FILE__ ) . '/wings/fs_write.php';
|
89 |
$module = new BVFSWriteCallback();
|
90 |
break;
|
|
|
|
|
|
|
|
|
91 |
default:
|
92 |
require_once dirname( __FILE__ ) . '/wings/misc.php';
|
93 |
$module = new BVMiscCallback($this);
|
88 |
require_once dirname( __FILE__ ) . '/wings/fs_write.php';
|
89 |
$module = new BVFSWriteCallback();
|
90 |
break;
|
91 |
+
case 'actlg':
|
92 |
+
require_once dirname( __FILE__ ) . '/wings/actlog.php';
|
93 |
+
$module = new BVActLogCallback($this);
|
94 |
+
break;
|
95 |
default:
|
96 |
require_once dirname( __FILE__ ) . '/wings/misc.php';
|
97 |
$module = new BVMiscCallback($this);
|
callback/wings/account.php
CHANGED
@@ -24,19 +24,15 @@ class BVAccountCallback extends BVCallbackBase {
|
|
24 |
$resp = array("status" => BVAccount::remove($this->settings, $params['public']));
|
25 |
break;
|
26 |
case "updt":
|
27 |
-
$
|
28 |
-
$info['email'] = $params['email'];
|
29 |
-
$info['url'] = $params['url'];
|
30 |
-
$info['pubkey'] = $params['pubkey'];
|
31 |
-
$account->updateInfo($info);
|
32 |
$resp = array("status" => BVAccount::exists($this->settings, $params['pubkey']));
|
33 |
break;
|
34 |
case "updtapikey":
|
35 |
BVAccount::updateApiPublicKey($this->settings, $params['pubkey']);
|
36 |
$resp = array("status" => $this->settings->getOption(BVAccount::$api_public_key));
|
37 |
break;
|
38 |
-
case "
|
39 |
-
$resp = array("status" => $settings->deleteOption('
|
40 |
break;
|
41 |
case "rmbvkeys":
|
42 |
$resp = array("status" => $settings->deleteOption('bvKeys'));
|
24 |
$resp = array("status" => BVAccount::remove($this->settings, $params['public']));
|
25 |
break;
|
26 |
case "updt":
|
27 |
+
$account->updateInfo($params);
|
|
|
|
|
|
|
|
|
28 |
$resp = array("status" => BVAccount::exists($this->settings, $params['pubkey']));
|
29 |
break;
|
30 |
case "updtapikey":
|
31 |
BVAccount::updateApiPublicKey($this->settings, $params['pubkey']);
|
32 |
$resp = array("status" => $this->settings->getOption(BVAccount::$api_public_key));
|
33 |
break;
|
34 |
+
case "rmbvscrt":
|
35 |
+
$resp = array("status" => $settings->deleteOption('bvSecretKey'));
|
36 |
break;
|
37 |
case "rmbvkeys":
|
38 |
$resp = array("status" => $settings->deleteOption('bvKeys'));
|
callback/wings/actlog.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!defined('ABSPATH')) exit;
|
4 |
+
if (!class_exists('BVActLogCallback')) :
|
5 |
+
|
6 |
+
require_once dirname( __FILE__ ) . '/../../wp_actlog.php';
|
7 |
+
|
8 |
+
class BVActLogCallback extends BVCallbackBase {
|
9 |
+
public $db;
|
10 |
+
public $settings;
|
11 |
+
|
12 |
+
public function __construct($callback_handler) {
|
13 |
+
$this->db = $callback_handler->db;
|
14 |
+
$this->settings = $callback_handler->settings;
|
15 |
+
}
|
16 |
+
|
17 |
+
public function dropActLogTable() {
|
18 |
+
return $this->db->dropBVTable(BVWPActLog::$actlog_table);
|
19 |
+
}
|
20 |
+
|
21 |
+
public function createActLogTable($usedbdelta = false) {
|
22 |
+
$db = $this->db;
|
23 |
+
$charset_collate = $db->getCharsetCollate();
|
24 |
+
$table = $this->db->getBVTable(BVWPActLog::$actlog_table);
|
25 |
+
$query = "CREATE TABLE $table (
|
26 |
+
id bigint(20) NOT NULL AUTO_INCREMENT,
|
27 |
+
site_id int NOT NULL,
|
28 |
+
user_id int DEFAULT 0,
|
29 |
+
username text DEFAULT '',
|
30 |
+
request_id text DEFAULT '',
|
31 |
+
ip varchar(20) DEFAULT '',
|
32 |
+
event_type varchar(40) NOT NULL DEFAULT '',
|
33 |
+
event_data mediumtext NOT NULL,
|
34 |
+
time int,
|
35 |
+
PRIMARY KEY (id)
|
36 |
+
) $charset_collate;";
|
37 |
+
return $db->createTable($query, BVWPActLog::$actlog_table, $usedbdelta);
|
38 |
+
}
|
39 |
+
|
40 |
+
public function process($request) {
|
41 |
+
$settings = $this->settings;
|
42 |
+
$params = $request->params;
|
43 |
+
switch ($request->method) {
|
44 |
+
case "truncactlogtable":
|
45 |
+
$resp = array("status" => $this->db->truncateBVTable(BVWPActLog::$actlog_table));
|
46 |
+
break;
|
47 |
+
case "dropactlogtable":
|
48 |
+
$resp = array("status" => $this->dropActLogTable());
|
49 |
+
break;
|
50 |
+
case "createactlogtable":
|
51 |
+
$usedbdelta = array_key_exists('usedbdelta', $params);
|
52 |
+
$resp = array("status" => $this->createActLogTable($usedbdelta));
|
53 |
+
break;
|
54 |
+
default:
|
55 |
+
$resp = false;
|
56 |
+
}
|
57 |
+
return $resp;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
endif;
|
callback/wings/db.php
CHANGED
@@ -15,7 +15,6 @@ class BVDBCallback extends BVCallbackBase {
|
|
15 |
$this->db = $callback_handler->db;
|
16 |
$this->account = $callback_handler->account;
|
17 |
$this->siteinfo = $callback_handler->siteinfo;
|
18 |
-
$this->bvinfo = $callback_handler->bvinfo;
|
19 |
}
|
20 |
|
21 |
public function getLastID($pkeys, $end_row) {
|
@@ -43,7 +42,9 @@ class BVDBCallback extends BVCallbackBase {
|
|
43 |
$data = array();
|
44 |
$data["offset"] = $offset;
|
45 |
$data["size"] = $srows;
|
46 |
-
$
|
|
|
|
|
47 |
array_push($tinfo, $data);
|
48 |
if (!empty($pkeys) && $srows > 0) {
|
49 |
$end_row = end($rows);
|
@@ -64,13 +65,65 @@ class BVDBCallback extends BVCallbackBase {
|
|
64 |
return $result;
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
public function process($request) {
|
68 |
$db = $this->db;
|
69 |
$params = $request->params;
|
70 |
$stream_init_info = BVStream::startStream($this->account, $request);
|
71 |
|
72 |
-
|
73 |
-
|
74 |
if (array_key_exists('stream', $stream_init_info)) {
|
75 |
$this->stream = $stream_init_info['stream'];
|
76 |
switch ($request->method) {
|
@@ -101,6 +154,31 @@ class BVDBCallback extends BVCallbackBase {
|
|
101 |
$table = urldecode($params['table']);
|
102 |
$resp = array("create" => $db->showTableCreate($table));
|
103 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
case "getrowscount":
|
105 |
$table = urldecode($params['table']);
|
106 |
$resp = array("count" => $db->rowsCount($table));
|
@@ -175,4 +253,4 @@ class BVDBCallback extends BVCallbackBase {
|
|
175 |
return $resp;
|
176 |
}
|
177 |
}
|
178 |
-
endif;
|
15 |
$this->db = $callback_handler->db;
|
16 |
$this->account = $callback_handler->account;
|
17 |
$this->siteinfo = $callback_handler->siteinfo;
|
|
|
18 |
}
|
19 |
|
20 |
public function getLastID($pkeys, $end_row) {
|
42 |
$data = array();
|
43 |
$data["offset"] = $offset;
|
44 |
$data["size"] = $srows;
|
45 |
+
$serialized_rows = serialize($rows);
|
46 |
+
$data['md5'] = md5($serialized_rows);
|
47 |
+
$data['length'] = strlen($serialized_rows);
|
48 |
array_push($tinfo, $data);
|
49 |
if (!empty($pkeys) && $srows > 0) {
|
50 |
$end_row = end($rows);
|
65 |
return $result;
|
66 |
}
|
67 |
|
68 |
+
public function getCreateTableQueries($tables) {
|
69 |
+
$resp = array();
|
70 |
+
foreach($tables as $table) {
|
71 |
+
$tname = urldecode($table);
|
72 |
+
$resp[$tname] = array("create" => $this->db->showTableCreate($table));
|
73 |
+
}
|
74 |
+
return $resp;
|
75 |
+
}
|
76 |
+
|
77 |
+
public function checkTables($tables, $type) {
|
78 |
+
$resp = array();
|
79 |
+
foreach($tables as $table) {
|
80 |
+
$tname = urldecode($table);
|
81 |
+
$resp[$tname] = array("status" => $this->db->checkTable($table, $type));
|
82 |
+
}
|
83 |
+
return $resp;
|
84 |
+
}
|
85 |
+
|
86 |
+
public function describeTables($tables) {
|
87 |
+
$resp = array();
|
88 |
+
foreach($tables as $table) {
|
89 |
+
$tname = urldecode($table);
|
90 |
+
$resp[$tname] = array("description" => $this->db->describeTable($table));
|
91 |
+
}
|
92 |
+
return $resp;
|
93 |
+
}
|
94 |
+
|
95 |
+
public function checkTablesExist($tables) {
|
96 |
+
$resp = array();
|
97 |
+
foreach($tables as $table) {
|
98 |
+
$tname = urldecode($table);
|
99 |
+
$resp[$tname] = array("tblexists" => $this->db->isTablePresent($table));
|
100 |
+
}
|
101 |
+
return $resp;
|
102 |
+
}
|
103 |
+
|
104 |
+
public function getTablesRowCount($tables) {
|
105 |
+
$resp = array();
|
106 |
+
foreach($tables as $table) {
|
107 |
+
$tname = urldecode($table);
|
108 |
+
$resp[$tname] = array("count" => $this->db->rowsCount($table));
|
109 |
+
}
|
110 |
+
return $resp;
|
111 |
+
}
|
112 |
+
|
113 |
+
public function getTablesKeys($tables) {
|
114 |
+
$resp = array();
|
115 |
+
foreach($tables as $table) {
|
116 |
+
$tname = urldecode($table);
|
117 |
+
$resp[$tname] = array("keys" => $this->db->tableKeys($table));
|
118 |
+
}
|
119 |
+
return $resp;
|
120 |
+
}
|
121 |
+
|
122 |
public function process($request) {
|
123 |
$db = $this->db;
|
124 |
$params = $request->params;
|
125 |
$stream_init_info = BVStream::startStream($this->account, $request);
|
126 |
|
|
|
|
|
127 |
if (array_key_exists('stream', $stream_init_info)) {
|
128 |
$this->stream = $stream_init_info['stream'];
|
129 |
switch ($request->method) {
|
154 |
$table = urldecode($params['table']);
|
155 |
$resp = array("create" => $db->showTableCreate($table));
|
156 |
break;
|
157 |
+
case "tblskys":
|
158 |
+
$tables = $params['tables'];
|
159 |
+
$resp = $this->getTablesKeys($tables);
|
160 |
+
break;
|
161 |
+
case "getmlticrt":
|
162 |
+
$tables = $params['tables'];
|
163 |
+
$resp = $this->getCreateTableQueries($tables);
|
164 |
+
break;
|
165 |
+
case "desctbls":
|
166 |
+
$tables = $params['tables'];
|
167 |
+
$resp = $this->describeTables($tables);
|
168 |
+
break;
|
169 |
+
case "mltirwscount":
|
170 |
+
$tables = $params['tables'];
|
171 |
+
$resp = $this->getTablesRowCount($tables);
|
172 |
+
break;
|
173 |
+
case "chktabls":
|
174 |
+
$tables = $params['tables'];
|
175 |
+
$type = urldecode($params['type']);
|
176 |
+
$resp = $this->checkTables($tables, $type);
|
177 |
+
break;
|
178 |
+
case "chktablsxist":
|
179 |
+
$tables = $params['tables'];
|
180 |
+
$resp = $this->checkTablesExist($tables);
|
181 |
+
break;
|
182 |
case "getrowscount":
|
183 |
$table = urldecode($params['table']);
|
184 |
$resp = array("count" => $db->rowsCount($table));
|
253 |
return $resp;
|
254 |
}
|
255 |
}
|
256 |
+
endif;
|
callback/wings/fs.php
CHANGED
@@ -26,7 +26,7 @@ class BVFSCallback extends BVCallbackBase {
|
|
26 |
if (is_link($absfile)) {
|
27 |
$fdata["link"] = @readlink($absfile);
|
28 |
}
|
29 |
-
if ($md5 === true) {
|
30 |
$fdata["md5"] = $this->calculateMd5($absfile, array(), 0, 0, 0);
|
31 |
}
|
32 |
} else {
|
@@ -196,7 +196,7 @@ class BVFSCallback extends BVCallbackBase {
|
|
196 |
$result["missingfiles"][] = $file;
|
197 |
continue;
|
198 |
}
|
199 |
-
if ($md5 === true) {
|
200 |
$fdata["md5"] = $this->calculateMd5($absfile, $fdata, $offset, $limit, $bsize);
|
201 |
}
|
202 |
$result["stats"][] = $fdata;
|
@@ -245,8 +245,6 @@ class BVFSCallback extends BVCallbackBase {
|
|
245 |
function process($request) {
|
246 |
$params = $request->params;
|
247 |
$stream_init_info = BVStream::startStream($this->account, $request);
|
248 |
-
|
249 |
-
|
250 |
|
251 |
if (array_key_exists('stream', $stream_init_info)) {
|
252 |
$this->stream = $stream_init_info['stream'];
|
26 |
if (is_link($absfile)) {
|
27 |
$fdata["link"] = @readlink($absfile);
|
28 |
}
|
29 |
+
if ($md5 === true && !is_dir($absfile)) {
|
30 |
$fdata["md5"] = $this->calculateMd5($absfile, array(), 0, 0, 0);
|
31 |
}
|
32 |
} else {
|
196 |
$result["missingfiles"][] = $file;
|
197 |
continue;
|
198 |
}
|
199 |
+
if ($md5 === true && !is_dir($absfile)) {
|
200 |
$fdata["md5"] = $this->calculateMd5($absfile, $fdata, $offset, $limit, $bsize);
|
201 |
}
|
202 |
$result["stats"][] = $fdata;
|
245 |
function process($request) {
|
246 |
$params = $request->params;
|
247 |
$stream_init_info = BVStream::startStream($this->account, $request);
|
|
|
|
|
248 |
|
249 |
if (array_key_exists('stream', $stream_init_info)) {
|
250 |
$this->stream = $stream_init_info['stream'];
|
callback/wings/fs_write.php
CHANGED
@@ -35,7 +35,7 @@ class BVFSWriteCallback extends BVCallbackBase {
|
|
35 |
return $result;
|
36 |
}
|
37 |
|
38 |
-
public function makeDirs($dirs) {
|
39 |
$result = array();
|
40 |
|
41 |
foreach($dirs as $dir) {
|
@@ -53,7 +53,7 @@ class BVFSWriteCallback extends BVCallbackBase {
|
|
53 |
|
54 |
} else {
|
55 |
|
56 |
-
$dir_result['status'] = mkdir($dir);
|
57 |
if ($dir_result['status'] === false) {
|
58 |
$dir_result['error'] = "MKDIR_FAILED";
|
59 |
}
|
@@ -411,7 +411,7 @@ class BVFSWriteCallback extends BVCallbackBase {
|
|
411 |
$resp = $this->doChmod($params['pathinfos']);
|
412 |
break;
|
413 |
case "mkdr":
|
414 |
-
$resp = $this->makeDirs($params['dirs']);
|
415 |
break;
|
416 |
case "rmdr":
|
417 |
$resp = $this->removeDirs($params['dirs']);
|
35 |
return $result;
|
36 |
}
|
37 |
|
38 |
+
public function makeDirs($dirs, $permissions = 0777, $recursive = true) {
|
39 |
$result = array();
|
40 |
|
41 |
foreach($dirs as $dir) {
|
53 |
|
54 |
} else {
|
55 |
|
56 |
+
$dir_result['status'] = mkdir($dir, $permissions, $recursive);
|
57 |
if ($dir_result['status'] === false) {
|
58 |
$dir_result['error'] = "MKDIR_FAILED";
|
59 |
}
|
411 |
$resp = $this->doChmod($params['pathinfos']);
|
412 |
break;
|
413 |
case "mkdr":
|
414 |
+
$resp = $this->makeDirs($params['dirs'], $params['permissions'], $params['recursive']);
|
415 |
break;
|
416 |
case "rmdr":
|
417 |
$resp = $this->removeDirs($params['dirs']);
|
callback/wings/info.php
CHANGED
@@ -129,6 +129,7 @@ class BVInfoCallback extends BVCallbackBase {
|
|
129 |
'dbprefix' => $db->dbprefix(),
|
130 |
'wpmu' => $siteinfo->isMultisite(),
|
131 |
'mainsite' => $siteinfo->isMainSite(),
|
|
|
132 |
'name' => get_bloginfo('name'),
|
133 |
'siteurl' => $siteinfo->siteurl(),
|
134 |
'homeurl' => $siteinfo->homeurl(),
|
@@ -210,6 +211,7 @@ class BVInfoCallback extends BVCallbackBase {
|
|
210 |
$data['protect'] = $settings->getOption('bvptconf');
|
211 |
$data['brand'] = $settings->getOption($this->bvinfo->brand_option);
|
212 |
$data['badgeinfo'] = $settings->getOption($this->bvinfo->badgeinfo);
|
|
|
213 |
}
|
214 |
|
215 |
public function dbconf(&$info) {
|
129 |
'dbprefix' => $db->dbprefix(),
|
130 |
'wpmu' => $siteinfo->isMultisite(),
|
131 |
'mainsite' => $siteinfo->isMainSite(),
|
132 |
+
'main_site_id' => $siteinfo->getMainSiteId(),
|
133 |
'name' => get_bloginfo('name'),
|
134 |
'siteurl' => $siteinfo->siteurl(),
|
135 |
'homeurl' => $siteinfo->homeurl(),
|
211 |
$data['protect'] = $settings->getOption('bvptconf');
|
212 |
$data['brand'] = $settings->getOption($this->bvinfo->brand_option);
|
213 |
$data['badgeinfo'] = $settings->getOption($this->bvinfo->badgeinfo);
|
214 |
+
$data[$this->bvinfo->services_option_name] = $this->bvinfo->config;
|
215 |
}
|
216 |
|
217 |
public function dbconf(&$info) {
|
callback/wings/misc.php
CHANGED
@@ -8,12 +8,14 @@ class BVMiscCallback extends BVCallbackBase {
|
|
8 |
public $bvinfo;
|
9 |
public $siteinfo;
|
10 |
public $account;
|
|
|
11 |
|
12 |
public function __construct($callback_handler) {
|
13 |
$this->settings = $callback_handler->settings;
|
14 |
$this->siteinfo = $callback_handler->siteinfo;
|
15 |
$this->account = $callback_handler->account;
|
16 |
$this->bvinfo = new BVInfo($callback_handler->settings);
|
|
|
17 |
}
|
18 |
|
19 |
public function refreshPluginUpdates() {
|
@@ -53,6 +55,12 @@ class BVMiscCallback extends BVCallbackBase {
|
|
53 |
$resp = array_merge($resp, $this->account->info());
|
54 |
$resp = array_merge($resp, $this->bvinfo->info());
|
55 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
case "enablebadge":
|
57 |
$option = $bvinfo->badgeinfo;
|
58 |
$badgeinfo = array();
|
@@ -94,12 +102,13 @@ class BVMiscCallback extends BVCallbackBase {
|
|
94 |
case "dlttrsnt":
|
95 |
$resp = array("dlttrsnt" => $settings->deleteTransient($params['key']));
|
96 |
break;
|
97 |
-
case "setmanulsignup":
|
98 |
-
$resp = array("setmanulsignup" => $settings->updateOption("bvmanualsignup", true));
|
99 |
-
break;
|
100 |
case "setbvss":
|
101 |
$resp = array("status" => $settings->updateOption('bv_site_settings', $params['bv_site_settings']));
|
102 |
break;
|
|
|
|
|
|
|
|
|
103 |
default:
|
104 |
$resp = false;
|
105 |
}
|
8 |
public $bvinfo;
|
9 |
public $siteinfo;
|
10 |
public $account;
|
11 |
+
public $bvapi;
|
12 |
|
13 |
public function __construct($callback_handler) {
|
14 |
$this->settings = $callback_handler->settings;
|
15 |
$this->siteinfo = $callback_handler->siteinfo;
|
16 |
$this->account = $callback_handler->account;
|
17 |
$this->bvinfo = new BVInfo($callback_handler->settings);
|
18 |
+
$this->bvapi = new BVWPAPI($callback_handler->settings);
|
19 |
}
|
20 |
|
21 |
public function refreshPluginUpdates() {
|
55 |
$resp = array_merge($resp, $this->account->info());
|
56 |
$resp = array_merge($resp, $this->bvinfo->info());
|
57 |
break;
|
58 |
+
case "pngbv":
|
59 |
+
$info = array();
|
60 |
+
$this->siteinfo->basic($info);
|
61 |
+
$this->bvapi->pingbv('/bvapi/pingbv', $info);
|
62 |
+
$resp = array("status" => true);
|
63 |
+
break;
|
64 |
case "enablebadge":
|
65 |
$option = $bvinfo->badgeinfo;
|
66 |
$badgeinfo = array();
|
102 |
case "dlttrsnt":
|
103 |
$resp = array("dlttrsnt" => $settings->deleteTransient($params['key']));
|
104 |
break;
|
|
|
|
|
|
|
105 |
case "setbvss":
|
106 |
$resp = array("status" => $settings->updateOption('bv_site_settings', $params['bv_site_settings']));
|
107 |
break;
|
108 |
+
case "stsrvcs":
|
109 |
+
$settings->updateOption($bvinfo->services_option_name, $params['services']);
|
110 |
+
$resp = array("stsrvcs" => $settings->getOption($bvinfo->services_option_name));
|
111 |
+
break;
|
112 |
default:
|
113 |
$resp = false;
|
114 |
}
|
callback/wings/protect.php
CHANGED
@@ -76,6 +76,17 @@ class BVProtectCallback extends BVCallbackBase {
|
|
76 |
$this->settings->updateOption('bvptconf', $params['conf']);
|
77 |
$resp = array('conf' => $this->settings->getOption('bvptconf'));
|
78 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
case "gtraddr":
|
80 |
$raddr = array_key_exists('REMOTE_ADDR', $_SERVER) ? $_SERVER['REMOTE_ADDR'] : false;
|
81 |
$resp = array("raddr" => $raddr);
|
76 |
$this->settings->updateOption('bvptconf', $params['conf']);
|
77 |
$resp = array('conf' => $this->settings->getOption('bvptconf'));
|
78 |
break;
|
79 |
+
case "gtrulcnf":
|
80 |
+
$resp = array('conf' => $this->settings->getOption('bvruleset'));
|
81 |
+
break;
|
82 |
+
case "clrrulcnf":
|
83 |
+
$this->settings->deleteOption('bvruleset');
|
84 |
+
$resp = array("clearconfig" => true);
|
85 |
+
break;
|
86 |
+
case "dorulcnf":
|
87 |
+
$this->settings->updateOption('bvruleset', $params['conf']);
|
88 |
+
$resp = array('conf' => $this->settings->getOption('bvruleset'));
|
89 |
+
break;
|
90 |
case "gtraddr":
|
91 |
$raddr = array_key_exists('REMOTE_ADDR', $_SERVER) ? $_SERVER['REMOTE_ADDR'] : false;
|
92 |
$resp = array("raddr" => $raddr);
|
callback/wings/watch.php
CHANGED
@@ -129,6 +129,16 @@ class BVWatchCallback extends BVCallbackBase {
|
|
129 |
}
|
130 |
}
|
131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
$resp["status"] = "done";
|
133 |
break;
|
134 |
case "rmdata":
|
129 |
}
|
130 |
}
|
131 |
|
132 |
+
if (array_key_exists('actlog', $params)) {
|
133 |
+
require_once dirname( __FILE__ ) . '/../../wp_actlog.php';
|
134 |
+
$actlog_params = $params['actlog'];
|
135 |
+
$limit = intval(urldecode($actlog_params['limit']));
|
136 |
+
$filter = urldecode($actlog_params['filter']);
|
137 |
+
$db->deleteBVTableContent(BVWPActLog::$actlog_table, $actlog_params['rmfilter']);
|
138 |
+
$table = $db->getBVTable(BVWPActLog::$actlog_table);
|
139 |
+
$resp["actlogs"] = $this->getData($table, $limit, $filter);
|
140 |
+
}
|
141 |
+
|
142 |
$resp["status"] = "done";
|
143 |
break;
|
144 |
case "rmdata":
|
info.php
CHANGED
@@ -4,26 +4,39 @@ if (!defined('ABSPATH')) exit;
|
|
4 |
if (!class_exists('BVInfo')) :
|
5 |
class BVInfo {
|
6 |
public $settings;
|
|
|
7 |
public $plugname = 'bvbackup';
|
8 |
public $brandname = 'BlogVault';
|
9 |
public $badgeinfo = 'bvbadge';
|
10 |
public $ip_header_option = 'bvipheader';
|
11 |
public $brand_option = 'bvbrand';
|
12 |
-
public $version = '4.
|
13 |
public $webpage = 'https://blogvault.net';
|
14 |
public $appurl = 'https://app.blogvault.net';
|
15 |
public $slug = 'blogvault-real-time-backup/blogvault.php';
|
16 |
public $plug_redirect = 'bvredirect';
|
17 |
public $logo = '../img/bvlogo.png';
|
18 |
public $brand_icon = '/img/icon.png';
|
|
|
19 |
|
20 |
public function __construct($settings) {
|
21 |
$this->settings = $settings;
|
|
|
22 |
}
|
23 |
|
24 |
-
public function
|
25 |
-
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
public function getBrandInfo() {
|
@@ -79,6 +92,14 @@ if (!class_exists('BVInfo')) :
|
|
79 |
$this->isActivePlugin();
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
public function isActivateRedirectSet() {
|
83 |
return ($this->settings->getOption($this->plug_redirect) === 'yes') ? true : false;
|
84 |
}
|
4 |
if (!class_exists('BVInfo')) :
|
5 |
class BVInfo {
|
6 |
public $settings;
|
7 |
+
public $config;
|
8 |
public $plugname = 'bvbackup';
|
9 |
public $brandname = 'BlogVault';
|
10 |
public $badgeinfo = 'bvbadge';
|
11 |
public $ip_header_option = 'bvipheader';
|
12 |
public $brand_option = 'bvbrand';
|
13 |
+
public $version = '4.54';
|
14 |
public $webpage = 'https://blogvault.net';
|
15 |
public $appurl = 'https://app.blogvault.net';
|
16 |
public $slug = 'blogvault-real-time-backup/blogvault.php';
|
17 |
public $plug_redirect = 'bvredirect';
|
18 |
public $logo = '../img/bvlogo.png';
|
19 |
public $brand_icon = '/img/icon.png';
|
20 |
+
public $services_option_name = 'bvconfig';
|
21 |
|
22 |
public function __construct($settings) {
|
23 |
$this->settings = $settings;
|
24 |
+
$this->config = $this->settings->getOption($this->services_option_name);
|
25 |
}
|
26 |
|
27 |
+
public function canSetCWBranding() {
|
28 |
+
if (BVWPSiteInfo::isCWServer()) {
|
29 |
+
|
30 |
+
$bot_protect_accounts = BVAccount::accountsByType($this->settings, 'botprotect');
|
31 |
+
if (sizeof($bot_protect_accounts) >= 1)
|
32 |
+
return true;
|
33 |
+
|
34 |
+
$bot_protect_accounts = BVAccount::accountsByPattern($this->settings, 'email', '/@cw_user\.com$/');
|
35 |
+
if (sizeof($bot_protect_accounts) >= 1)
|
36 |
+
return true;
|
37 |
+
}
|
38 |
+
|
39 |
+
return false;
|
40 |
}
|
41 |
|
42 |
public function getBrandInfo() {
|
92 |
$this->isActivePlugin();
|
93 |
}
|
94 |
|
95 |
+
public function isServiceActive($service) {
|
96 |
+
$bvconfig = $this->config;
|
97 |
+
if ($bvconfig && array_key_exists('services', $bvconfig)) {
|
98 |
+
return in_array($service, $bvconfig['services']) && $this->isActivePlugin();
|
99 |
+
}
|
100 |
+
return false;
|
101 |
+
}
|
102 |
+
|
103 |
public function isActivateRedirectSet() {
|
104 |
return ($this->settings->getOption($this->plug_redirect) === 'yes') ? true : false;
|
105 |
}
|
protect/fw/config.php
CHANGED
@@ -15,6 +15,7 @@ class BVFWConfig {
|
|
15 |
public $cookiePath;
|
16 |
public $cookieDomain;
|
17 |
public $loggingMode;
|
|
|
18 |
|
19 |
public static $requests_table = 'fw_requests';
|
20 |
public static $roleLevels = array(
|
@@ -36,6 +37,7 @@ class BVFWConfig {
|
|
36 |
$this->cookieKey = array_key_exists('cookiekey', $confHash) ? $confHash['cookiekey'] : "";
|
37 |
$this->cookiePath = array_key_exists('cookiepath', $confHash) ? $confHash['cookiepath'] : "";
|
38 |
$this->cookieDomain = array_key_exists('cookiedomain', $confHash) ? $confHash['cookiedomain'] : "";
|
|
|
39 |
}
|
40 |
|
41 |
#mode
|
@@ -77,10 +79,9 @@ class BVFWConfig {
|
|
77 |
const LOGGING_MODE_COMPLETE = 2;
|
78 |
const LOGGING_MODE_DISABLED = 3;
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
public static $
|
83 |
-
public static $validDeletableFiles = array('mc.conf', 'mc_ips.conf', 'malcare-waf.php', 'mc.log', 'mc_data');
|
84 |
|
85 |
public function isActive() {
|
86 |
return ($this->mode !== BVFWConfig::DISABLED);
|
@@ -113,5 +114,9 @@ class BVFWConfig {
|
|
113 |
public function isLoggingDisabled() {
|
114 |
return ($this->loggingMode === BVFWConfig::LOGGING_MODE_DISABLED);
|
115 |
}
|
|
|
|
|
|
|
|
|
116 |
}
|
117 |
endif;
|
15 |
public $cookiePath;
|
16 |
public $cookieDomain;
|
17 |
public $loggingMode;
|
18 |
+
public $rulesMode;
|
19 |
|
20 |
public static $requests_table = 'fw_requests';
|
21 |
public static $roleLevels = array(
|
37 |
$this->cookieKey = array_key_exists('cookiekey', $confHash) ? $confHash['cookiekey'] : "";
|
38 |
$this->cookiePath = array_key_exists('cookiepath', $confHash) ? $confHash['cookiepath'] : "";
|
39 |
$this->cookieDomain = array_key_exists('cookiedomain', $confHash) ? $confHash['cookiedomain'] : "";
|
40 |
+
$this->rulesMode = array_key_exists('rulesmode', $confHash) ? intval($confHash['rulesmode']) : BVFWConfig::DISABLED;
|
41 |
}
|
42 |
|
43 |
#mode
|
79 |
const LOGGING_MODE_COMPLETE = 2;
|
80 |
const LOGGING_MODE_DISABLED = 3;
|
81 |
|
82 |
+
#Valid mc_data filenames (not used anywhere)
|
83 |
+
public static $validMcDataFilenames = array('mc.conf', 'mc_ips.conf', 'mc_rules.json');
|
84 |
+
public static $validDeletableFiles = array('mc.conf', 'mc_ips.conf', 'malcare-waf.php', 'mc.log', 'mc_data', 'mc_rules.json');
|
|
|
85 |
|
86 |
public function isActive() {
|
87 |
return ($this->mode !== BVFWConfig::DISABLED);
|
114 |
public function isLoggingDisabled() {
|
115 |
return ($this->loggingMode === BVFWConfig::LOGGING_MODE_DISABLED);
|
116 |
}
|
117 |
+
|
118 |
+
public function isRulesModeEnabled() {
|
119 |
+
return ($this->rulesMode === BVFWConfig::PROTECT);
|
120 |
+
}
|
121 |
}
|
122 |
endif;
|
protect/fw/fw.php
CHANGED
@@ -3,6 +3,8 @@
|
|
3 |
if (! (defined('ABSPATH') || defined('MCDATAPATH')) ) exit;
|
4 |
if (!class_exists('BVFW')) :
|
5 |
|
|
|
|
|
6 |
class BVFW {
|
7 |
public $bvinfo;
|
8 |
public $request;
|
@@ -10,6 +12,9 @@ class BVFW {
|
|
10 |
public $ipstore;
|
11 |
public $category;
|
12 |
public $logger;
|
|
|
|
|
|
|
13 |
|
14 |
const SQLIREGEX = '/(?:[^\\w<]|\\/\\*\\![0-9]*|^)(?:
|
15 |
@@HOSTNAME|
|
@@ -47,12 +52,15 @@ class BVFW {
|
|
47 |
const BYPASS_COOKIE = "bvfw-bypass-cookie";
|
48 |
const IP_COOKIE = "bvfw-ip-cookie";
|
49 |
|
50 |
-
public function __construct($logger, $confHash, $ip, $bvinfo, $ipstore) {
|
51 |
$this->config = new BVFWConfig($confHash);
|
52 |
$this->request = new BVWPRequest($ip);
|
53 |
$this->bvinfo = $bvinfo;
|
54 |
$this->ipstore = $ipstore;
|
55 |
$this->logger = $logger;
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
public function setcookie($name, $value, $expire) {
|
@@ -202,18 +210,26 @@ class BVFW {
|
|
202 |
return false;
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
public function execute() {
|
206 |
if ($this->config->canProfileReqInfo()) {
|
207 |
$result = array();
|
208 |
|
209 |
if ($this->request->getMethod() === 'POST' &&
|
210 |
preg_match('/(admin-ajax.php|admin-post.php)$/', $this->request->getPath())) {
|
211 |
-
$result += $this->profileRequestInfo(array("action" => $this->request->
|
212 |
true, 'BODY[');
|
213 |
}
|
214 |
-
$result += $this->profileRequestInfo($this->request->
|
215 |
$this->config->isReqProfilingModeDebug(), 'BODY[');
|
216 |
-
$result += $this->profileRequestInfo($this->request->
|
217 |
true, 'GET[');
|
218 |
$result += $this->profileRequestInfo($this->request->getFiles(),
|
219 |
true, 'FILES[');
|
@@ -226,6 +242,13 @@ class BVFW {
|
|
226 |
if ($this->isBlacklistedIP()) {
|
227 |
$this->terminateRequest(BVWPRequest::BLACKLISTED);
|
228 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
}
|
231 |
|
@@ -258,6 +281,7 @@ class BVFW {
|
|
258 |
$result = array();
|
259 |
if (is_array($params)) {
|
260 |
foreach ($params as $key => $value) {
|
|
|
261 |
$key = $prefix . $key;
|
262 |
if (is_array($value)) {
|
263 |
$result = $result + $this->profileRequestInfo($value, $debug, $key . '[', $obraces + 1);
|
@@ -266,7 +290,7 @@ class BVFW {
|
|
266 |
$result[$key] = array();
|
267 |
$valsize = $this->getLength($value);
|
268 |
$result[$key]["size"] = $valsize;
|
269 |
-
if ($debug === true && $valsize < 256) {
|
270 |
$result[$key]["value"] = $value;
|
271 |
continue;
|
272 |
}
|
@@ -335,13 +359,69 @@ class BVFW {
|
|
335 |
$result[$key]["file"] = true;
|
336 |
}
|
337 |
|
338 |
-
if ($this->matchCount(BVFW::SQLIREGEX, $value)
|
339 |
$result[$key]["sql"] = true;
|
340 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
}
|
342 |
}
|
343 |
}
|
344 |
return $result;
|
345 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
}
|
347 |
endif;
|
3 |
if (! (defined('ABSPATH') || defined('MCDATAPATH')) ) exit;
|
4 |
if (!class_exists('BVFW')) :
|
5 |
|
6 |
+
require_once dirname( __FILE__ ) . '/rule_evaluator.php';
|
7 |
+
|
8 |
class BVFW {
|
9 |
public $bvinfo;
|
10 |
public $request;
|
12 |
public $ipstore;
|
13 |
public $category;
|
14 |
public $logger;
|
15 |
+
public $ruleSet;
|
16 |
+
public $ruleEvaluator;
|
17 |
+
public $break_rule_evaluation;
|
18 |
|
19 |
const SQLIREGEX = '/(?:[^\\w<]|\\/\\*\\![0-9]*|^)(?:
|
20 |
@@HOSTNAME|
|
52 |
const BYPASS_COOKIE = "bvfw-bypass-cookie";
|
53 |
const IP_COOKIE = "bvfw-ip-cookie";
|
54 |
|
55 |
+
public function __construct($logger, $confHash, $ip, $bvinfo, $ipstore, $ruleSet) {
|
56 |
$this->config = new BVFWConfig($confHash);
|
57 |
$this->request = new BVWPRequest($ip);
|
58 |
$this->bvinfo = $bvinfo;
|
59 |
$this->ipstore = $ipstore;
|
60 |
$this->logger = $logger;
|
61 |
+
$this->ruleSet = $ruleSet;
|
62 |
+
$this->ruleEvaluator = new BVFWRuleEvaluator($this->request);
|
63 |
+
$this->break_rule_evaluation = false;
|
64 |
}
|
65 |
|
66 |
public function setcookie($name, $value, $expire) {
|
210 |
return false;
|
211 |
}
|
212 |
|
213 |
+
public function canLogValue($key) {
|
214 |
+
$skip_keys = array('password' => true, 'passwd' => true, 'pwd' => true);
|
215 |
+
if (isset($skip_keys[$key])) {
|
216 |
+
return false;
|
217 |
+
}
|
218 |
+
return true;
|
219 |
+
}
|
220 |
+
|
221 |
public function execute() {
|
222 |
if ($this->config->canProfileReqInfo()) {
|
223 |
$result = array();
|
224 |
|
225 |
if ($this->request->getMethod() === 'POST' &&
|
226 |
preg_match('/(admin-ajax.php|admin-post.php)$/', $this->request->getPath())) {
|
227 |
+
$result += $this->profileRequestInfo(array("action" => $this->request->getPostParams('action')),
|
228 |
true, 'BODY[');
|
229 |
}
|
230 |
+
$result += $this->profileRequestInfo($this->request->getPostParams(),
|
231 |
$this->config->isReqProfilingModeDebug(), 'BODY[');
|
232 |
+
$result += $this->profileRequestInfo($this->request->getGetParams(),
|
233 |
true, 'GET[');
|
234 |
$result += $this->profileRequestInfo($this->request->getFiles(),
|
235 |
true, 'FILES[');
|
242 |
if ($this->isBlacklistedIP()) {
|
243 |
$this->terminateRequest(BVWPRequest::BLACKLISTED);
|
244 |
}
|
245 |
+
if ($this->config->isRulesModeEnabled()) {
|
246 |
+
if ($this->ruleSet) {
|
247 |
+
$this->evaluateRules($this->ruleSet);
|
248 |
+
} else {
|
249 |
+
$this->request->updateRulesInfo('errors', 'ruleset', 'Invalid RuleSet');
|
250 |
+
}
|
251 |
+
}
|
252 |
}
|
253 |
}
|
254 |
|
281 |
$result = array();
|
282 |
if (is_array($params)) {
|
283 |
foreach ($params as $key => $value) {
|
284 |
+
$original_key = $key;
|
285 |
$key = $prefix . $key;
|
286 |
if (is_array($value)) {
|
287 |
$result = $result + $this->profileRequestInfo($value, $debug, $key . '[', $obraces + 1);
|
290 |
$result[$key] = array();
|
291 |
$valsize = $this->getLength($value);
|
292 |
$result[$key]["size"] = $valsize;
|
293 |
+
if ($debug === true && $valsize < 256 && $this->canLogValue($original_key)) {
|
294 |
$result[$key]["value"] = $value;
|
295 |
continue;
|
296 |
}
|
359 |
$result[$key]["file"] = true;
|
360 |
}
|
361 |
|
362 |
+
if ($this->matchCount(BVFW::SQLIREGEX, $value) > 2) {
|
363 |
$result[$key]["sql"] = true;
|
364 |
}
|
365 |
+
|
366 |
+
if (preg_match('/(?:\.{2}[\/]+)/', $value)) {
|
367 |
+
$result[$key]["path_traversal"] = true;
|
368 |
+
}
|
369 |
+
|
370 |
+
if (preg_match('/\\b(?i:eval)\\s*\\(\\s*(?i:base64_decode|exec|file_get_contents|gzinflate|passthru|shell_exec|stripslashes|system)\\s*\\(/', $value)) {
|
371 |
+
$result[$key]["php_eval"] = true;
|
372 |
+
}
|
373 |
}
|
374 |
}
|
375 |
}
|
376 |
return $result;
|
377 |
}
|
378 |
+
|
379 |
+
public function evaluateRules($ruleSet) {
|
380 |
+
foreach ($ruleSet as $rule) {
|
381 |
+
$id = $rule["id"];
|
382 |
+
$ruleLogic = $rule["rule_logic"];
|
383 |
+
$actions = $rule["actions"];
|
384 |
+
$min_rule_engine_ver = $rule["min_rule_engine_ver"];
|
385 |
+
$this->ruleEvaluator->resetErrors();
|
386 |
+
|
387 |
+
if (BVFWRuleEvaluator::VERSION >= $min_rule_engine_ver) {
|
388 |
+
if ($this->ruleEvaluator->evaluateRule($ruleLogic) && empty($this->ruleEvaluator->getErrors())) {
|
389 |
+
$this->request->updateRulesInfo('matched_rules', $id, null);
|
390 |
+
$this->executeActions($actions);
|
391 |
+
} elseif (!empty($this->ruleEvaluator->getErrors())) {
|
392 |
+
$this->request->updateRulesInfo("errors", (string) $id, $this->ruleEvaluator->getErrors());
|
393 |
+
}
|
394 |
+
}
|
395 |
+
if ($this->break_rule_evaluation) {
|
396 |
+
return;
|
397 |
+
}
|
398 |
+
}
|
399 |
+
}
|
400 |
+
|
401 |
+
function executeActions($actions){
|
402 |
+
foreach($actions as $action) {
|
403 |
+
switch ($action["type"]) {
|
404 |
+
case "ALLOW":
|
405 |
+
$this->break_rule_evaluation = true;
|
406 |
+
return;
|
407 |
+
case "BLOCK":
|
408 |
+
$this->terminateRequest(BVWPRequest::BLACKLISTED);
|
409 |
+
return;
|
410 |
+
case "INSPECT":
|
411 |
+
//TODO
|
412 |
+
//call_user_func_array(array($this, "profileRequestInfo"), $this->ruleEvaluator->getArgs($action["args"]));
|
413 |
+
break;
|
414 |
+
case "DEBUG":
|
415 |
+
//TODO
|
416 |
+
break;
|
417 |
+
case "SCRUB":
|
418 |
+
//TODO
|
419 |
+
break;
|
420 |
+
case "FILTER":
|
421 |
+
//TODO
|
422 |
+
break;
|
423 |
+
}
|
424 |
+
}
|
425 |
+
}
|
426 |
}
|
427 |
endif;
|
protect/fw/request.php
CHANGED
@@ -11,10 +11,10 @@ class BVWPRequest {
|
|
11 |
private $ip;
|
12 |
private $method;
|
13 |
private $path;
|
14 |
-
private $
|
15 |
private $timestamp;
|
16 |
private $uri;
|
17 |
-
private $
|
18 |
private $cookies;
|
19 |
private $respcode;
|
20 |
private $status;
|
@@ -27,9 +27,9 @@ class BVWPRequest {
|
|
27 |
const BYPASSED = 3;
|
28 |
|
29 |
#category
|
30 |
-
const BLACKLISTED
|
31 |
-
const WHITELISTED
|
32 |
-
const NORMAL
|
33 |
|
34 |
public function __construct($ip) {
|
35 |
$fileNames = array();
|
@@ -44,9 +44,9 @@ class BVWPRequest {
|
|
44 |
$this->setCategory(BVWPRequest::NORMAL);
|
45 |
$this->setStatus(BVWpRequest::ALLOWED);
|
46 |
$this->setTimestamp(time());
|
47 |
-
$this->
|
48 |
$this->setCookies($_COOKIE);
|
49 |
-
$this->
|
50 |
$this->setFiles($_FILES);
|
51 |
if (!empty($_FILES)) {
|
52 |
foreach ($_FILES as $input => $file) {
|
@@ -103,8 +103,8 @@ class BVWPRequest {
|
|
103 |
$this->category = $category;
|
104 |
}
|
105 |
|
106 |
-
public function
|
107 |
-
$this->
|
108 |
}
|
109 |
|
110 |
public function setCookies($cookies) {
|
@@ -143,8 +143,8 @@ class BVWPRequest {
|
|
143 |
$this->path = $path;
|
144 |
}
|
145 |
|
146 |
-
public function
|
147 |
-
$this->
|
148 |
}
|
149 |
|
150 |
public function setTimestamp($timestamp) {
|
@@ -155,8 +155,10 @@ class BVWPRequest {
|
|
155 |
$this->uri = $uri;
|
156 |
}
|
157 |
|
158 |
-
public function updateRulesInfo($
|
159 |
-
$this->rulesInfo[$
|
|
|
|
|
160 |
}
|
161 |
|
162 |
public function getRulesInfo() {
|
@@ -227,15 +229,15 @@ class BVWPRequest {
|
|
227 |
}
|
228 |
return null;
|
229 |
}
|
230 |
-
|
231 |
-
public function
|
232 |
if (func_num_args() > 0) {
|
233 |
$args = func_get_args();
|
234 |
-
return $this->getKeyVal($this->
|
235 |
}
|
236 |
-
return $this->
|
237 |
}
|
238 |
-
|
239 |
public function getCookies() {
|
240 |
if (func_num_args() > 0) {
|
241 |
$args = func_get_args();
|
@@ -244,21 +246,33 @@ class BVWPRequest {
|
|
244 |
return $this->cookies;
|
245 |
}
|
246 |
|
247 |
-
public function
|
248 |
if (func_num_args() > 0) {
|
249 |
$args = func_get_args();
|
250 |
-
return $this->getKeyVal($this->
|
251 |
}
|
252 |
-
return $this->
|
253 |
}
|
254 |
-
|
|
|
|
|
|
|
|
|
255 |
public function getHeader($key) {
|
256 |
if (array_key_exists($key, $this->headers)) {
|
257 |
return $this->headers[$key];
|
258 |
}
|
259 |
return null;
|
260 |
}
|
261 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
262 |
public function getFiles() {
|
263 |
if (func_num_args() > 0) {
|
264 |
$args = func_get_args();
|
@@ -298,5 +312,22 @@ class BVWPRequest {
|
|
298 |
public function getTimestamp() {
|
299 |
return $this->timestamp;
|
300 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
}
|
302 |
-
endif;
|
11 |
private $ip;
|
12 |
private $method;
|
13 |
private $path;
|
14 |
+
private $getParams;
|
15 |
private $timestamp;
|
16 |
private $uri;
|
17 |
+
private $postParams;
|
18 |
private $cookies;
|
19 |
private $respcode;
|
20 |
private $status;
|
27 |
const BYPASSED = 3;
|
28 |
|
29 |
#category
|
30 |
+
const BLACKLISTED = 1;
|
31 |
+
const WHITELISTED = 2;
|
32 |
+
const NORMAL = 3;
|
33 |
|
34 |
public function __construct($ip) {
|
35 |
$fileNames = array();
|
44 |
$this->setCategory(BVWPRequest::NORMAL);
|
45 |
$this->setStatus(BVWpRequest::ALLOWED);
|
46 |
$this->setTimestamp(time());
|
47 |
+
$this->setGetParams($_GET);
|
48 |
$this->setCookies($_COOKIE);
|
49 |
+
$this->setPostParams($_POST);
|
50 |
$this->setFiles($_FILES);
|
51 |
if (!empty($_FILES)) {
|
52 |
foreach ($_FILES as $input => $file) {
|
103 |
$this->category = $category;
|
104 |
}
|
105 |
|
106 |
+
public function setPostParams($postParams) {
|
107 |
+
$this->postParams = $postParams;
|
108 |
}
|
109 |
|
110 |
public function setCookies($cookies) {
|
143 |
$this->path = $path;
|
144 |
}
|
145 |
|
146 |
+
public function setGetParams($getParams) {
|
147 |
+
$this->getParams = $getParams;
|
148 |
}
|
149 |
|
150 |
public function setTimestamp($timestamp) {
|
155 |
$this->uri = $uri;
|
156 |
}
|
157 |
|
158 |
+
public function updateRulesInfo($category, $sub_category, $value) {
|
159 |
+
$rule_info = (array_key_exists($category, $this->rulesInfo)) ? $this->rulesInfo[$category] : array();
|
160 |
+
$rule_info[$sub_category] = $value;
|
161 |
+
$this->rulesInfo[$category] = $rule_info;
|
162 |
}
|
163 |
|
164 |
public function getRulesInfo() {
|
229 |
}
|
230 |
return null;
|
231 |
}
|
232 |
+
|
233 |
+
public function getPostParams() {
|
234 |
if (func_num_args() > 0) {
|
235 |
$args = func_get_args();
|
236 |
+
return $this->getKeyVal($this->postParams, $args);
|
237 |
}
|
238 |
+
return $this->postParams;
|
239 |
}
|
240 |
+
|
241 |
public function getCookies() {
|
242 |
if (func_num_args() > 0) {
|
243 |
$args = func_get_args();
|
246 |
return $this->cookies;
|
247 |
}
|
248 |
|
249 |
+
public function getGetParams() {
|
250 |
if (func_num_args() > 0) {
|
251 |
$args = func_get_args();
|
252 |
+
return $this->getKeyVal($this->getParams, $args);
|
253 |
}
|
254 |
+
return $this->getParams;
|
255 |
}
|
256 |
+
|
257 |
+
public function getAllParams() {
|
258 |
+
return array("getParams" => $this->getParams, "postParams" => $this->postParams);
|
259 |
+
}
|
260 |
+
|
261 |
public function getHeader($key) {
|
262 |
if (array_key_exists($key, $this->headers)) {
|
263 |
return $this->headers[$key];
|
264 |
}
|
265 |
return null;
|
266 |
}
|
267 |
+
|
268 |
+
public function getHeaders() {
|
269 |
+
if (func_num_args() > 0) {
|
270 |
+
$args = func_get_args();
|
271 |
+
return $this->getKeyVal($this->headers, $args);
|
272 |
+
}
|
273 |
+
return $this->headers;
|
274 |
+
}
|
275 |
+
|
276 |
public function getFiles() {
|
277 |
if (func_num_args() > 0) {
|
278 |
$args = func_get_args();
|
312 |
public function getTimestamp() {
|
313 |
return $this->timestamp;
|
314 |
}
|
315 |
+
|
316 |
+
public function getServerValue($key) {
|
317 |
+
if (isset($_SERVER) && array_key_exists($key, $_SERVER)) {
|
318 |
+
return $_SERVER[$key];
|
319 |
+
}
|
320 |
+
return false;
|
321 |
+
}
|
322 |
+
|
323 |
+
public function getUserRoleLevel() {
|
324 |
+
// TODO
|
325 |
+
// Handle prepend level using custom cookies.
|
326 |
+
return 0;
|
327 |
+
}
|
328 |
+
|
329 |
+
public function isUserRoleLevel($level) {
|
330 |
+
return ($level === $this->getUserRoleLevel());
|
331 |
+
}
|
332 |
}
|
333 |
+
endif;
|
protect/fw/rule_evaluator.php
ADDED
@@ -0,0 +1,375 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!(defined('ABSPATH') || defined('MCDATAPATH'))) exit;
|
4 |
+
if (!class_exists('BVFWRuleEvaluator')) :
|
5 |
+
|
6 |
+
class BVFWRuleEvaluator {
|
7 |
+
private $request;
|
8 |
+
|
9 |
+
const VERSION = 0.2;
|
10 |
+
|
11 |
+
public function __construct($request) {
|
12 |
+
$this->request = $request;
|
13 |
+
}
|
14 |
+
|
15 |
+
function getErrors() {
|
16 |
+
return $this->errors;
|
17 |
+
}
|
18 |
+
|
19 |
+
function resetErrors() {
|
20 |
+
$this->errors = array();
|
21 |
+
}
|
22 |
+
|
23 |
+
// ================================ Functions for type checking ========================================
|
24 |
+
function isNumeric($value) {
|
25 |
+
return (preg_match('/^\d+$/', $value));
|
26 |
+
}
|
27 |
+
|
28 |
+
function isRegularWord($value) {
|
29 |
+
return (preg_match('/^\w+$/', $value));
|
30 |
+
}
|
31 |
+
|
32 |
+
function isSpecialWord($value) {
|
33 |
+
return (preg_match('/^\S+$/', $value));
|
34 |
+
}
|
35 |
+
|
36 |
+
function isRegularSentence($value) {
|
37 |
+
return (preg_match('/^[\w\s]+$/', $value));
|
38 |
+
}
|
39 |
+
|
40 |
+
function isSpecialCharsSentence($value) {
|
41 |
+
return (preg_match('/^[\w\W]+$/', $value));
|
42 |
+
}
|
43 |
+
|
44 |
+
function isLink($value) {
|
45 |
+
return (preg_match('/^(http|ftp)s?:\/\/\S+$/i', $value));
|
46 |
+
}
|
47 |
+
|
48 |
+
function isFileUpload($value) {
|
49 |
+
$file = $this->getFiles($value);
|
50 |
+
if (is_array($file) && in_array('tmp_name', $file)) {
|
51 |
+
return is_uploaded_file($file['tmp_name']);
|
52 |
+
}
|
53 |
+
return false;
|
54 |
+
}
|
55 |
+
|
56 |
+
function isIpv4($value) {
|
57 |
+
return (preg_match('/^\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b$/x', $value));
|
58 |
+
}
|
59 |
+
|
60 |
+
function isEmbededIpv4($value) {
|
61 |
+
return (preg_match('/\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\b/x', $value));
|
62 |
+
}
|
63 |
+
|
64 |
+
function isIpv6($value) {
|
65 |
+
return (preg_match('/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/x', $value));
|
66 |
+
}
|
67 |
+
|
68 |
+
function isEmbededIpv6($value) {
|
69 |
+
return (preg_match('/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/x', $value));
|
70 |
+
}
|
71 |
+
|
72 |
+
function isEmail($value) {
|
73 |
+
return (preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/', $value));
|
74 |
+
}
|
75 |
+
|
76 |
+
function isEmbededEmail($value) {
|
77 |
+
return (preg_match('/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}/', $value));
|
78 |
+
}
|
79 |
+
|
80 |
+
function isEmbededLink($value) {
|
81 |
+
return (preg_match('/(http|ftp)s?:\/\/\S+$/i', $value));
|
82 |
+
}
|
83 |
+
|
84 |
+
function isEmbededHtml($value) {
|
85 |
+
return (preg_match('/<(html|head|title|base|link|meta|style|picture|source|img|iframe|embed|object|param|video|audio|track|map|area|form|label|input|button|select|datalist|optgroup|option|textarea|output|progress|meter|fieldset|legend|script|noscript|template|slot|canvas)/ix', $value));
|
86 |
+
}
|
87 |
+
|
88 |
+
function isFile($value) {
|
89 |
+
return (preg_match('/\.(jpg|jpeg|png|gif|ico|pdf|doc|docx|ppt|pptx|pps|ppsx|odt|xls|zip|gzip|xlsx|psd|mp3|m4a|ogg|wav|mp4|m4v|mov|wmv|avi|mpg|ogv|3gp|3g2|php|html|phtml|js|css)/ix', $value));
|
90 |
+
}
|
91 |
+
|
92 |
+
function isPathTraversal($value) {
|
93 |
+
return (preg_match('/(?:\.{2}[\/]+)/', $value));
|
94 |
+
}
|
95 |
+
|
96 |
+
function isPhpEval($value) {
|
97 |
+
return (preg_match('/\\b(?i:eval)\\s*\\(\\s*(?i:base64_decode|exec|file_get_contents|gzinflate|passthru|shell_exec|stripslashes|system)\\s*\\(/', $value));
|
98 |
+
}
|
99 |
+
|
100 |
+
// ================================ Functions to perform operations ========================================
|
101 |
+
function contains($val, $subject) {
|
102 |
+
if (is_array($val)) {
|
103 |
+
return in_array($val, $subject);
|
104 |
+
}
|
105 |
+
return strpos((string) $subject, (string) $val) !== false;
|
106 |
+
}
|
107 |
+
|
108 |
+
function notContains($val, $subject) {
|
109 |
+
return !$this->contains($val, $subject);
|
110 |
+
}
|
111 |
+
|
112 |
+
function match($pattern, $subject) {
|
113 |
+
if (is_array($subject)) {
|
114 |
+
foreach ($subject as $k => $v) {
|
115 |
+
if ($this->match($pattern, $v)) {
|
116 |
+
return true;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
return false;
|
120 |
+
}
|
121 |
+
$resp = preg_match((string) $pattern, (string) $subject);
|
122 |
+
if ($resp === false) {
|
123 |
+
array_push($this->errors, array("preg_match", $subject));
|
124 |
+
} else if ($resp > 0) {
|
125 |
+
return true;
|
126 |
+
}
|
127 |
+
return false;
|
128 |
+
}
|
129 |
+
|
130 |
+
function notMatch($pattern, $subject) {
|
131 |
+
return !$this->match($pattern, $subject);
|
132 |
+
}
|
133 |
+
|
134 |
+
function matchCount($pattern, $subject) {
|
135 |
+
$count = 0;
|
136 |
+
if (is_array($subject)) {
|
137 |
+
foreach ($subject as $val) {
|
138 |
+
$count += $this->matchCount($pattern, $val);
|
139 |
+
}
|
140 |
+
return $count;
|
141 |
+
}
|
142 |
+
$count = preg_match_all((string) $pattern, (string) $subject, $matches);
|
143 |
+
if ($count === false) {
|
144 |
+
array_push($this->errors, array("preg_match_all", $subject));
|
145 |
+
}
|
146 |
+
return $count;
|
147 |
+
}
|
148 |
+
|
149 |
+
function maxMatchCount($pattern, $subject) {
|
150 |
+
$count = 0;
|
151 |
+
if (is_array($subject)) {
|
152 |
+
foreach ($subject as $val) {
|
153 |
+
$count = max($count, $this->matchCount($pattern, $val));
|
154 |
+
}
|
155 |
+
return $count;
|
156 |
+
}
|
157 |
+
$count = preg_match_all((string) $pattern, (string) $subject, $matches);
|
158 |
+
if ($count === false) {
|
159 |
+
array_push($this->errors, array("preg_match_all", $subject));
|
160 |
+
}
|
161 |
+
return $count;
|
162 |
+
}
|
163 |
+
|
164 |
+
function equals($val, $subject) {
|
165 |
+
return ($val == $subject);
|
166 |
+
}
|
167 |
+
|
168 |
+
function notEquals($val, $subject) {
|
169 |
+
return !$this->equals($val, $subject);
|
170 |
+
}
|
171 |
+
|
172 |
+
function isIdentical($val, $subject) {
|
173 |
+
return ($val === $subject);
|
174 |
+
}
|
175 |
+
|
176 |
+
function notIdentical($val, $subject) {
|
177 |
+
return !$this->isIdentical($val, $subject);
|
178 |
+
}
|
179 |
+
|
180 |
+
function greaterThan($val, $subject) {
|
181 |
+
return ($subject > $val);
|
182 |
+
}
|
183 |
+
|
184 |
+
function greaterThanEqualTo($val, $subject) {
|
185 |
+
return ($subject >= $val);
|
186 |
+
}
|
187 |
+
|
188 |
+
function lessThan($val, $subject) {
|
189 |
+
return ($subject < $val);
|
190 |
+
}
|
191 |
+
|
192 |
+
function lessThanEqualTo($val, $subject) {
|
193 |
+
return ($subject <= $val);
|
194 |
+
}
|
195 |
+
|
196 |
+
function lengthGreaterThan($val, $subject) {
|
197 |
+
return (strlen((string) $subject) > $val);
|
198 |
+
}
|
199 |
+
|
200 |
+
function lengthLessThan($val, $subject) {
|
201 |
+
return (strlen((string) $subject) < $val);
|
202 |
+
}
|
203 |
+
|
204 |
+
function md5Equals($val, $subject) {
|
205 |
+
return (md5((string) $subject) === $val);
|
206 |
+
}
|
207 |
+
|
208 |
+
function compareMultipleSubjects($func, $args, $subjects) {
|
209 |
+
// TODO
|
210 |
+
}
|
211 |
+
|
212 |
+
// ================================ Functions to get request data ========================================
|
213 |
+
function getReqInfo($key) {
|
214 |
+
return $this->request->getReqInfo($key);
|
215 |
+
}
|
216 |
+
|
217 |
+
function getPath() {
|
218 |
+
return $this->request->getPath();
|
219 |
+
}
|
220 |
+
|
221 |
+
function getServerValue($key) {
|
222 |
+
return $this->request->getServerValue($key);
|
223 |
+
}
|
224 |
+
|
225 |
+
function getHeader($key) {
|
226 |
+
return $this->request->getHeader($key);
|
227 |
+
}
|
228 |
+
|
229 |
+
function getHeaders() {
|
230 |
+
return $this->request->getHeaders();
|
231 |
+
}
|
232 |
+
|
233 |
+
function getPostParams() {
|
234 |
+
if (func_num_args() > 0) {
|
235 |
+
$args = func_get_args();
|
236 |
+
return $this->request->getPostParams($args);
|
237 |
+
}
|
238 |
+
return $this->request->getPostParams();
|
239 |
+
}
|
240 |
+
|
241 |
+
function getReqMethod() {
|
242 |
+
return $this->request->getMethod();
|
243 |
+
}
|
244 |
+
|
245 |
+
function getGetParams() {
|
246 |
+
if (func_num_args() > 0) {
|
247 |
+
$args = func_get_args();
|
248 |
+
return $this->request->getGetParams($args);
|
249 |
+
}
|
250 |
+
return $this->request->getGetParams();
|
251 |
+
}
|
252 |
+
|
253 |
+
function getCookies() {
|
254 |
+
if (func_num_args() > 0) {
|
255 |
+
$args = func_get_args();
|
256 |
+
return $this->request->getCookies($args);
|
257 |
+
}
|
258 |
+
return $this->request->getCookies();
|
259 |
+
}
|
260 |
+
|
261 |
+
function getFiles() {
|
262 |
+
if (func_num_args() > 0) {
|
263 |
+
$args = func_get_args();
|
264 |
+
return $this->request->getFiles($args);
|
265 |
+
}
|
266 |
+
return $this->request->getFiles();
|
267 |
+
}
|
268 |
+
|
269 |
+
function getFileNames() {
|
270 |
+
if (func_num_args() > 0) {
|
271 |
+
$args = func_get_args();
|
272 |
+
return $this->request->getFileNames($args);
|
273 |
+
}
|
274 |
+
return $this->request->getFileNames();
|
275 |
+
}
|
276 |
+
|
277 |
+
function getHost() {
|
278 |
+
return $this->host;
|
279 |
+
}
|
280 |
+
|
281 |
+
function getURI() {
|
282 |
+
return $this->request->getURI();
|
283 |
+
}
|
284 |
+
|
285 |
+
function getIP() {
|
286 |
+
return $this->request->getIP();
|
287 |
+
}
|
288 |
+
|
289 |
+
function getTimestamp() {
|
290 |
+
return $this->request->getTimeStamp();
|
291 |
+
}
|
292 |
+
|
293 |
+
function getUserRoleLevel() {
|
294 |
+
return $this->request->getUserRoleLevel();
|
295 |
+
}
|
296 |
+
|
297 |
+
function isUserRoleLevel($level) {
|
298 |
+
return $this->request->isUserRoleLevel($level);
|
299 |
+
}
|
300 |
+
|
301 |
+
function getAllParams() {
|
302 |
+
return $this->request->getAllParams();
|
303 |
+
}
|
304 |
+
|
305 |
+
// ================================ Functions to evaluate rule logic ========================================
|
306 |
+
function evaluateRule($ruleLogic) {
|
307 |
+
return $this->evaluateExpression($ruleLogic);
|
308 |
+
}
|
309 |
+
|
310 |
+
function evaluateExpression($expr) {
|
311 |
+
switch ($expr["type"]) {
|
312 |
+
case "AND" :
|
313 |
+
$loperand = $this->getValue($expr["left_operand"]);
|
314 |
+
$roperand = $this->getValue($expr["right_operand"]);
|
315 |
+
return ($loperand && $roperand);
|
316 |
+
case "OR" :
|
317 |
+
$loperand = $this->getValue($expr["left_operand"]);
|
318 |
+
$roperand = $this->getValue($expr["right_operand"]);
|
319 |
+
return ($loperand || $roperand);
|
320 |
+
case "NOT" :
|
321 |
+
return !$this->getValue($expr["value"]);
|
322 |
+
case "FUNCTION" :
|
323 |
+
return $this->executeFunctionCall($expr);
|
324 |
+
default :
|
325 |
+
break;
|
326 |
+
}
|
327 |
+
}
|
328 |
+
|
329 |
+
function fetchConstantValue($name) {
|
330 |
+
$value = constant($name);
|
331 |
+
if ($value) {
|
332 |
+
return $value;
|
333 |
+
}
|
334 |
+
array_push($this->errors, array("fetch_constant_value", $name));
|
335 |
+
return false;
|
336 |
+
}
|
337 |
+
|
338 |
+
function getArgs($args) {
|
339 |
+
$_args = array();
|
340 |
+
foreach ($args as $arg) {
|
341 |
+
array_push($_args, $this->getValue($arg));
|
342 |
+
}
|
343 |
+
return $_args;
|
344 |
+
}
|
345 |
+
|
346 |
+
function executeFunctionCall($func) {
|
347 |
+
$name = $func["name"];
|
348 |
+
$handler = array($this, $name);
|
349 |
+
if (!is_callable($handler)) {
|
350 |
+
array_push($this->errors, array("execute_function_call", "function_not_allowed", $name));
|
351 |
+
return false;
|
352 |
+
}
|
353 |
+
return call_user_func_array($handler, $this->getArgs($func["args"]));
|
354 |
+
}
|
355 |
+
|
356 |
+
function getValue($expr) {
|
357 |
+
switch ($expr["type"]) {
|
358 |
+
case "NUMBER" :
|
359 |
+
return $expr["value"];
|
360 |
+
case "STRING" :
|
361 |
+
return $expr["value"];
|
362 |
+
case "STRING_WITH_QUOTES" :
|
363 |
+
$expr["value"] = preg_replace("/^('|\")/", "", $expr["value"]);
|
364 |
+
$expr["value"] = preg_replace("/('|\")$/", "", $expr["value"]);
|
365 |
+
return $expr["value"];
|
366 |
+
case "CONST" :
|
367 |
+
return $this->fetchConstantValue($expr["value"]);
|
368 |
+
case "FUNCTION" :
|
369 |
+
return $this->executeFunctionCall($expr);
|
370 |
+
default :
|
371 |
+
return $this->evaluateExpression($expr);
|
372 |
+
}
|
373 |
+
}
|
374 |
+
}
|
375 |
+
endif;
|
protect/prepend/protect.php
CHANGED
@@ -14,10 +14,12 @@ require_once dirname( __FILE__ ) . '/logger.php';
|
|
14 |
class BVPrependProtect {
|
15 |
public $mcConfFile;
|
16 |
public $mcIPsFile;
|
|
|
17 |
|
18 |
function __construct() {
|
19 |
$this->mcConfFile = MCDATAPATH . MCCONFKEY . '-' . 'mc.conf';
|
20 |
$this->mcIPsFile = MCDATAPATH . MCCONFKEY . '-' . 'mc_ips.conf';
|
|
|
21 |
}
|
22 |
|
23 |
public function parseFile($fname) {
|
@@ -36,6 +38,7 @@ require_once dirname( __FILE__ ) . '/logger.php';
|
|
36 |
public function run() {
|
37 |
$mcConf = $this->parseFile($this->mcConfFile);
|
38 |
$mcIPsConf = $this->parseFile($this->mcIPsFile);
|
|
|
39 |
|
40 |
if (!array_key_exists('time', $mcConf) || !isset($mcConf['time']) || !($mcConf['time'] > time() - (48*3600))) {
|
41 |
return false;
|
@@ -55,7 +58,7 @@ require_once dirname( __FILE__ ) . '/logger.php';
|
|
55 |
$fwlogger = new BVPrependLogger();
|
56 |
|
57 |
$fwConfHash = array_key_exists('fw', $mcConf) ? $mcConf['fw'] : array();
|
58 |
-
$fw = new BVFW($fwlogger, $fwConfHash, $ip, $bvinfo, $bvipstore);
|
59 |
|
60 |
if ($fw->isActive()) {
|
61 |
|
@@ -73,4 +76,4 @@ require_once dirname( __FILE__ ) . '/logger.php';
|
|
73 |
}
|
74 |
|
75 |
}
|
76 |
-
endif;
|
14 |
class BVPrependProtect {
|
15 |
public $mcConfFile;
|
16 |
public $mcIPsFile;
|
17 |
+
public $mcRulesFile;
|
18 |
|
19 |
function __construct() {
|
20 |
$this->mcConfFile = MCDATAPATH . MCCONFKEY . '-' . 'mc.conf';
|
21 |
$this->mcIPsFile = MCDATAPATH . MCCONFKEY . '-' . 'mc_ips.conf';
|
22 |
+
$this->mcRulesFile = MCDATAPATH . MCCONFKEY . '-' . 'mc_rules.json';
|
23 |
}
|
24 |
|
25 |
public function parseFile($fname) {
|
38 |
public function run() {
|
39 |
$mcConf = $this->parseFile($this->mcConfFile);
|
40 |
$mcIPsConf = $this->parseFile($this->mcIPsFile);
|
41 |
+
$mcRuleSet = $this->parseFile($this->mcRulesFile);
|
42 |
|
43 |
if (!array_key_exists('time', $mcConf) || !isset($mcConf['time']) || !($mcConf['time'] > time() - (48*3600))) {
|
44 |
return false;
|
58 |
$fwlogger = new BVPrependLogger();
|
59 |
|
60 |
$fwConfHash = array_key_exists('fw', $mcConf) ? $mcConf['fw'] : array();
|
61 |
+
$fw = new BVFW($fwlogger, $fwConfHash, $ip, $bvinfo, $bvipstore, $mcRuleSet);
|
62 |
|
63 |
if ($fw->isActive()) {
|
64 |
|
76 |
}
|
77 |
|
78 |
}
|
79 |
+
endif;
|
protect/wp/lp/lp.php
CHANGED
@@ -183,10 +183,12 @@ class BVWPLP {
|
|
183 |
$this->setCategory(BVWPLP::UNBLOCKED);
|
184 |
} else {
|
185 |
$failed_attempts = $this->getLoginCount(BVWPLP::LOGINFAILURE, $this->ip);
|
186 |
-
if ($this->
|
|
|
|
|
187 |
$this->setCategory(BVWPLP::BLACKLISTED);
|
188 |
$this->terminateLogin();
|
189 |
-
} else if ($this->isKnownLogin()
|
190 |
$this->setCategory(BVWPLP::BYPASSED);
|
191 |
} else if ($this->isLoginBlocked()) {
|
192 |
$this->setCategory(BVWPLP::ALLBLOCKED);
|
183 |
$this->setCategory(BVWPLP::UNBLOCKED);
|
184 |
} else {
|
185 |
$failed_attempts = $this->getLoginCount(BVWPLP::LOGINFAILURE, $this->ip);
|
186 |
+
if ($this->isWhitelistedIP()) {
|
187 |
+
$this->setCategory(BVWPLP::BYPASSED);
|
188 |
+
} else if ($this->isBlacklistedIP()) {
|
189 |
$this->setCategory(BVWPLP::BLACKLISTED);
|
190 |
$this->terminateLogin();
|
191 |
+
} else if ($this->isKnownLogin()) {
|
192 |
$this->setCategory(BVWPLP::BYPASSED);
|
193 |
} else if ($this->isLoginBlocked()) {
|
194 |
$this->setCategory(BVWPLP::ALLBLOCKED);
|
protect/wp/protect.php
CHANGED
@@ -20,6 +20,10 @@ class BVProtect {
|
|
20 |
$this->db = $db;
|
21 |
}
|
22 |
|
|
|
|
|
|
|
|
|
23 |
public function run() {
|
24 |
$bvipstore = new BVIPStore($this->db);
|
25 |
$bvipstore->init();
|
@@ -36,7 +40,8 @@ class BVProtect {
|
|
36 |
$fwLogger = new BVLogger($this->db, BVFWConfig::$requests_table);
|
37 |
|
38 |
$fwConfHash = array_key_exists('fw', $config) ? $config['fw'] : array();
|
39 |
-
$
|
|
|
40 |
|
41 |
if ($fw->isActive()) {
|
42 |
|
@@ -55,8 +60,6 @@ class BVProtect {
|
|
55 |
}
|
56 |
}
|
57 |
|
58 |
-
add_action('clear_pt_config', array($this, 'uninstall'));
|
59 |
-
|
60 |
$lpConfHash = array_key_exists('lp', $config) ? $config['lp'] : array();
|
61 |
$lp = new BVWPLP($this->db, $this->settings, $ip, $bvipstore, $lpConfHash);
|
62 |
if ($lp->isActive()) {
|
@@ -69,7 +72,89 @@ class BVProtect {
|
|
69 |
$this->db->dropBVTable(BVFWConfig::$requests_table);
|
70 |
$this->db->dropBVTable(BVWPLPConfig::$requests_table);
|
71 |
$this->settings->deleteOption('bvptplug');
|
|
|
|
|
|
|
72 |
return true;
|
73 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
75 |
endif;
|
20 |
$this->db = $db;
|
21 |
}
|
22 |
|
23 |
+
public function init() {
|
24 |
+
add_action('clear_pt_config', array($this, 'uninstall'));
|
25 |
+
}
|
26 |
+
|
27 |
public function run() {
|
28 |
$bvipstore = new BVIPStore($this->db);
|
29 |
$bvipstore->init();
|
40 |
$fwLogger = new BVLogger($this->db, BVFWConfig::$requests_table);
|
41 |
|
42 |
$fwConfHash = array_key_exists('fw', $config) ? $config['fw'] : array();
|
43 |
+
$ruleSet = $this->getRuleSet();
|
44 |
+
$fw = new BVFW($fwLogger, $fwConfHash, $ip, $bvinfo, $bvipstore, $ruleSet);
|
45 |
|
46 |
if ($fw->isActive()) {
|
47 |
|
60 |
}
|
61 |
}
|
62 |
|
|
|
|
|
63 |
$lpConfHash = array_key_exists('lp', $config) ? $config['lp'] : array();
|
64 |
$lp = new BVWPLP($this->db, $this->settings, $ip, $bvipstore, $lpConfHash);
|
65 |
if ($lp->isActive()) {
|
72 |
$this->db->dropBVTable(BVFWConfig::$requests_table);
|
73 |
$this->db->dropBVTable(BVWPLPConfig::$requests_table);
|
74 |
$this->settings->deleteOption('bvptplug');
|
75 |
+
$this->remove_wp_prepend();
|
76 |
+
$this->remove_php_prepend();
|
77 |
+
$this->remove_mcdata();
|
78 |
return true;
|
79 |
}
|
80 |
+
|
81 |
+
private function remove_wp_prepend() {
|
82 |
+
$wp_conf_paths = array(ABSPATH . "wp-config.php", ABSPATH . "../wp-config.php");
|
83 |
+
if (file_exists($wp_conf_paths[0])) {
|
84 |
+
$fname = $wp_conf_paths[0];
|
85 |
+
} elseif (file_exists($wp_conf_paths[1])) {
|
86 |
+
$fname = $wp_conf_paths[1];
|
87 |
+
} else {
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
|
91 |
+
$content = file_get_contents($fname);
|
92 |
+
if ($content) {
|
93 |
+
$pattern = "@include '" . ABSPATH . "malcare-waf.php" . "';";
|
94 |
+
$modified_content = str_replace($pattern, "", $content);
|
95 |
+
if ($content !== $modified_content) {
|
96 |
+
file_put_contents($fname, $modified_content);
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
private function remove_php_prepend() {
|
102 |
+
$this->remove_htaccess_prepend();
|
103 |
+
$this->remove_userini_prepend();
|
104 |
+
}
|
105 |
+
|
106 |
+
private function remove_prepend($fname, $pattern) {
|
107 |
+
if (!file_exists($fname)) return;
|
108 |
+
|
109 |
+
$content = file_get_contents($fname);
|
110 |
+
if ($content) {
|
111 |
+
$modified_content = preg_replace($pattern, "", $content);
|
112 |
+
if ($content !== $modified_content) {
|
113 |
+
file_put_contents($fname, $modified_content);
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
private function remove_htaccess_prepend() {
|
119 |
+
$pattern = "/# MalCare WAF(.|\n)*# END MalCare WAF/i";
|
120 |
+
$this->remove_prepend(ABSPATH . ".htaccess", $pattern);
|
121 |
+
}
|
122 |
+
|
123 |
+
private function remove_userini_prepend() {
|
124 |
+
$pattern = "/; MalCare WAF(.|\n)*; END MalCare WAF/i";
|
125 |
+
$this->remove_prepend(ABSPATH . ".user.ini", $pattern);
|
126 |
+
}
|
127 |
+
|
128 |
+
private function remove_mcdata() {
|
129 |
+
$this->rrmdir($this->get_contdir() . "mc_data");
|
130 |
+
}
|
131 |
+
|
132 |
+
private function rrmdir($dir) {
|
133 |
+
if (is_dir($dir)) {
|
134 |
+
$objects = scandir($dir);
|
135 |
+
foreach ($objects as $object) {
|
136 |
+
if ($object != "." && $object != "..") {
|
137 |
+
if (is_dir($dir . "/" . $object) && !is_link($dir . "/" . $object)) {
|
138 |
+
rrmdir($dir . "/" . $object);
|
139 |
+
} else {
|
140 |
+
unlink($dir . "/" . $object);
|
141 |
+
}
|
142 |
+
}
|
143 |
+
}
|
144 |
+
rmdir($dir);
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
public function get_contdir() {
|
149 |
+
return defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR . "/" : ABSPATH . "wp-content/";
|
150 |
+
}
|
151 |
+
|
152 |
+
public function getRuleSet() {
|
153 |
+
$ruleSet = $this->settings->getOption('bvruleset');
|
154 |
+
if ($ruleSet) {
|
155 |
+
return $ruleSet;
|
156 |
+
}
|
157 |
+
return array();
|
158 |
+
}
|
159 |
}
|
160 |
endif;
|
readme.txt
CHANGED
@@ -6,7 +6,7 @@ Donate link: https://app.blogvault.net/home/signup
|
|
6 |
Requires at least: 4.0
|
7 |
Tested up to: 5.6
|
8 |
Requires PHP: 5.4.0
|
9 |
-
Stable tag: 4.
|
10 |
License: GPLv2 or later
|
11 |
License URI: [http://www.gnu.org/licenses/gpl-2.0.html](http://www.gnu.org/licenses/gpl-2.0.html)
|
12 |
|
@@ -247,6 +247,12 @@ These are available on our website: [Terms of Service](https://blogvault.net/tos
|
|
247 |
9. We power WordPress migration for WPEngine, Pantheon, FlyWheel, LiquidWeb, Cloudways, Savvii and many more. Need we say more?
|
248 |
|
249 |
== CHANGELOG ==
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
= 4.36 =
|
251 |
* Block WordPress auto update feature
|
252 |
* Improved scanfiles and filelist api
|
6 |
Requires at least: 4.0
|
7 |
Tested up to: 5.6
|
8 |
Requires PHP: 5.4.0
|
9 |
+
Stable tag: 4.54
|
10 |
License: GPLv2 or later
|
11 |
License URI: [http://www.gnu.org/licenses/gpl-2.0.html](http://www.gnu.org/licenses/gpl-2.0.html)
|
12 |
|
247 |
9. We power WordPress migration for WPEngine, Pantheon, FlyWheel, LiquidWeb, Cloudways, Savvii and many more. Need we say more?
|
248 |
|
249 |
== CHANGELOG ==
|
250 |
+
= 4.54 =
|
251 |
+
* Added Support For Multi Table Callbacks
|
252 |
+
* Added Firewall Rule Evaluator
|
253 |
+
* Added Activity Logs feature
|
254 |
+
* Minor Improvements
|
255 |
+
|
256 |
= 4.36 =
|
257 |
* Block WordPress auto update feature
|
258 |
* Improved scanfiles and filelist api
|
wp_actions.php
CHANGED
@@ -38,7 +38,7 @@ if (!class_exists('BVWPAction')) :
|
|
38 |
public static function uninstall() {
|
39 |
do_action('clear_pt_config');
|
40 |
do_action('clear_ip_store');
|
41 |
-
|
42 |
}
|
43 |
|
44 |
public function footerHandler() {
|
38 |
public static function uninstall() {
|
39 |
do_action('clear_pt_config');
|
40 |
do_action('clear_ip_store');
|
41 |
+
do_action('clear_dynsync_config');
|
42 |
}
|
43 |
|
44 |
public function footerHandler() {
|
wp_actlog.php
ADDED
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!defined('ABSPATH')) exit;
|
4 |
+
if (!class_exists('BVWPActLog')) :
|
5 |
+
|
6 |
+
class BVWPActLog {
|
7 |
+
|
8 |
+
public static $actlog_table = 'activities_store';
|
9 |
+
public $db;
|
10 |
+
public $settings;
|
11 |
+
public $bvinfo;
|
12 |
+
|
13 |
+
public function __construct($db, $settings, $info, $config) {
|
14 |
+
$this->db = $db;
|
15 |
+
$this->settings = $settings;
|
16 |
+
$this->bvinfo = $info;
|
17 |
+
$this->request_id = BVAccount::randString(16);
|
18 |
+
$this->ip_header = array_key_exists('ip_header', $config) ? $config['ip_header'] : false;
|
19 |
+
}
|
20 |
+
|
21 |
+
function init() {
|
22 |
+
$this->add_actions_and_listeners();
|
23 |
+
}
|
24 |
+
|
25 |
+
function get_post($post_id) {
|
26 |
+
$post = get_post($post_id);
|
27 |
+
$data = array('id' => $post_id);
|
28 |
+
if (!empty($post)) {
|
29 |
+
$data['title'] = $post->post_title;
|
30 |
+
$data['status'] = $post->post_status;
|
31 |
+
$data['type'] = $post->post_type;
|
32 |
+
$data['url'] = get_permalink($post_id);
|
33 |
+
$data['date'] = $post->post_date;
|
34 |
+
}
|
35 |
+
return $data;
|
36 |
+
}
|
37 |
+
|
38 |
+
function get_comment($comment_id) {
|
39 |
+
$comment = get_comment($comment_id);
|
40 |
+
$data = array('id' => $comment_id);
|
41 |
+
if (!empty($comment)) {
|
42 |
+
$data['author'] = $comment->comment_author;
|
43 |
+
}
|
44 |
+
return $data;
|
45 |
+
}
|
46 |
+
|
47 |
+
function get_term($term_id) {
|
48 |
+
$term = get_term($term_id);
|
49 |
+
$data = array('id' => $term_id);
|
50 |
+
if (!empty($term)) {
|
51 |
+
$data['name'] = $term->name;
|
52 |
+
$data['slug'] = $term->slug;
|
53 |
+
$data['taxonomy'] = $term->taxonomy;
|
54 |
+
}
|
55 |
+
return $data;
|
56 |
+
}
|
57 |
+
|
58 |
+
function get_user($user_id) {
|
59 |
+
$user = get_userdata($user_id);
|
60 |
+
$data = array('id' => $user_id);
|
61 |
+
if (!empty($user)) {
|
62 |
+
$data['username'] = $user->user_login;
|
63 |
+
$data['email'] = $user->user_email;
|
64 |
+
}
|
65 |
+
return $data;
|
66 |
+
}
|
67 |
+
|
68 |
+
function get_blog($blog_id) {
|
69 |
+
$blog = get_blog_details($blog_id);
|
70 |
+
$data = array('id' => $blog_id);
|
71 |
+
if (!empty($blog)) {
|
72 |
+
$data['name'] = $blog->blogname;
|
73 |
+
$data['url'] = $blog->path;
|
74 |
+
}
|
75 |
+
return $data;
|
76 |
+
}
|
77 |
+
|
78 |
+
function add_activity($event_data) {
|
79 |
+
$user = wp_get_current_user();
|
80 |
+
$values = array();
|
81 |
+
if (!empty($user)) {
|
82 |
+
$values["user_id"] = $user->ID;
|
83 |
+
$values["username"] = $user->user_login;
|
84 |
+
}
|
85 |
+
$values["request_id"] = $this->request_id;
|
86 |
+
$values["site_id"] = get_current_blog_id();
|
87 |
+
$values["ip"] = BVProtectBase::getIP($this->ip_header);
|
88 |
+
$values["event_type"] = current_filter();
|
89 |
+
$values["event_data"] = maybe_serialize($event_data);
|
90 |
+
$values["time"] = time();
|
91 |
+
$this->db->replaceIntoBVTable(BVWPActLog::$actlog_table, $values);
|
92 |
+
}
|
93 |
+
|
94 |
+
function user_login_handler($user_login, $user) {
|
95 |
+
$event_data = array("user" => $this->get_user($user->ID));
|
96 |
+
$this->add_activity($event_data);
|
97 |
+
}
|
98 |
+
|
99 |
+
function user_logout_handler($user_id) {
|
100 |
+
$user = $this->get_user($user_id);
|
101 |
+
$event_data = array("user" => $user);
|
102 |
+
$this->add_activity($event_data);
|
103 |
+
}
|
104 |
+
|
105 |
+
function password_reset_handler($user, $new_pass) {
|
106 |
+
if (!empty($user)) {
|
107 |
+
$event_data = array("user" => $this->get_user($user->ID));
|
108 |
+
$this->add_activity($event_data);
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
function comment_handler($comment_id) {
|
113 |
+
$comment = $this->get_comment($comment_id);
|
114 |
+
$post = $this->get_post($comment->comment_post_ID);
|
115 |
+
$event_data = array(
|
116 |
+
"comment" => $comment,
|
117 |
+
"post" => $post
|
118 |
+
);
|
119 |
+
$this->add_activity($event_data);
|
120 |
+
}
|
121 |
+
|
122 |
+
function comment_status_changed_handler($new_status, $old_status, $comment) {
|
123 |
+
$post = $this->get_post($comment->comment_post_ID);
|
124 |
+
$event_data = array(
|
125 |
+
"comment" => $this->get_comment($comment->comment_ID),
|
126 |
+
"post" => $post,
|
127 |
+
"old_status" => $old_status,
|
128 |
+
"new_status" => $new_status
|
129 |
+
);
|
130 |
+
$this->add_activity($event_data);
|
131 |
+
}
|
132 |
+
|
133 |
+
function post_handler($post_id) {
|
134 |
+
$post = $this->get_post($post_id);
|
135 |
+
$event_data = array(
|
136 |
+
"post" => $post
|
137 |
+
);
|
138 |
+
$this->add_activity($event_data);
|
139 |
+
}
|
140 |
+
|
141 |
+
function post_saved_handler($post_id, $post, $update) {
|
142 |
+
$post = $this->get_post($post_id);
|
143 |
+
$event_data = array(
|
144 |
+
"post" => $post,
|
145 |
+
"updated" => $update
|
146 |
+
);
|
147 |
+
$this->add_activity($event_data);
|
148 |
+
}
|
149 |
+
|
150 |
+
function term_handler($term_id) {
|
151 |
+
$term = $this->get_term($term_id);
|
152 |
+
$event_data = array(
|
153 |
+
"term" => $term,
|
154 |
+
);
|
155 |
+
$this->add_activity($event_data);
|
156 |
+
}
|
157 |
+
|
158 |
+
function term_updation_handler($data, $term_id) {
|
159 |
+
$term = $this->get_term($term_id);
|
160 |
+
$event_data = array(
|
161 |
+
"old_term" => $term,
|
162 |
+
"term" => $data
|
163 |
+
);
|
164 |
+
$this->add_activity($event_data);
|
165 |
+
return $data;
|
166 |
+
}
|
167 |
+
|
168 |
+
function term_deletion_handler($term_id) {
|
169 |
+
$event_data = array(
|
170 |
+
"term" => array("id" => $term_id)
|
171 |
+
);
|
172 |
+
$this->add_activity($event_data);
|
173 |
+
}
|
174 |
+
|
175 |
+
function user_handler($user_id) {
|
176 |
+
$user = $this->get_user($user_id);
|
177 |
+
$event_data = array(
|
178 |
+
"user" => $user,
|
179 |
+
);
|
180 |
+
$this->add_activity($event_data);
|
181 |
+
}
|
182 |
+
|
183 |
+
function user_update_handler($user_id, $old_userdata) {
|
184 |
+
$new_userdata = $this->get_user($user_id);
|
185 |
+
$event_data = array(
|
186 |
+
"old_user" => $this->get_user($old_userdata->ID),
|
187 |
+
"user" => $new_userdata,
|
188 |
+
);
|
189 |
+
$this->add_activity($event_data);
|
190 |
+
}
|
191 |
+
|
192 |
+
function plugin_action_handler($plugin) {
|
193 |
+
$event_data = array("plugin" => $plugin);
|
194 |
+
$this->add_activity($event_data);
|
195 |
+
}
|
196 |
+
|
197 |
+
function theme_action_handler($theme_name) {
|
198 |
+
$event_data = array("theme" => $theme_name);
|
199 |
+
$this->add_activity($event_data);
|
200 |
+
}
|
201 |
+
|
202 |
+
function mu_handler($blog_id) {
|
203 |
+
$blog = $this->get_blog($blog_id);
|
204 |
+
$event_data = array(
|
205 |
+
"blog" => $blog
|
206 |
+
);
|
207 |
+
$this->add_activity($event_data);
|
208 |
+
}
|
209 |
+
|
210 |
+
function mu_delete_handler($blog) {
|
211 |
+
$event_data = array(
|
212 |
+
"blog" => $this->get_blog($blog->blog_id)
|
213 |
+
);
|
214 |
+
$this->add_activity($event_data);
|
215 |
+
}
|
216 |
+
|
217 |
+
/* ADDING ACTION AND LISTENERS FOR SENSING EVENTS. */
|
218 |
+
public function add_actions_and_listeners() {
|
219 |
+
/* SENSORS FOR POST AND PAGE CHANGES */
|
220 |
+
add_action('pre_post_update', array($this, 'post_handler'));
|
221 |
+
add_action('save_post', array($this, 'post_saved_handler'), 10, 3);
|
222 |
+
add_action('post_stuck', array($this, 'post_handler'));
|
223 |
+
add_action('post_unstuck', array($this, 'post_handler'));
|
224 |
+
add_action('delete_post', array($this, 'post_handler'));
|
225 |
+
|
226 |
+
/* SENSORS FOR COMMENTS */
|
227 |
+
add_action('comment_post', array($this, 'comment_handler'));
|
228 |
+
add_action('edit_comment', array($this, 'comment_handler'));
|
229 |
+
add_action('transition_comment_status', array($this, 'comment_status_changed_handler'), 10, 3);
|
230 |
+
|
231 |
+
/* SENSORS FOR TAG AND CATEGORY CHANGES */
|
232 |
+
add_action('create_term', array($this, 'term_handler'));
|
233 |
+
add_action('pre_delete_term', array($this, 'term_handler'));
|
234 |
+
add_action('delete_term', array($this, 'term_deletion_handler'));
|
235 |
+
add_filter('wp_update_term_data', array($this, 'term_updation_handler'), 10, 2);
|
236 |
+
|
237 |
+
/* SENSORS FOR USER CHANGES*/
|
238 |
+
add_action('user_register', array($this, 'user_handler'));
|
239 |
+
add_action('wpmu_new_user', array($this, 'user_handler'));
|
240 |
+
add_action('profile_update', array($this, 'user_update_handler'), 10, 2);
|
241 |
+
add_action('delete_user', array($this, 'user_handler'));
|
242 |
+
add_action('wpmu_delete_user', array($this, 'user_handler'));
|
243 |
+
|
244 |
+
/* SENSORS FOR PLUGIN AND THEME*/
|
245 |
+
add_action('activate_plugin', array($this, 'plugin_action_handler'));
|
246 |
+
add_action('deactivate_plugin', array($this, 'plugin_action_handler'));
|
247 |
+
add_action('switch_theme', array($this, 'theme_action_handler'));
|
248 |
+
|
249 |
+
/* SENSORS FOR MULTISITE CHANGES */
|
250 |
+
add_action('wpmu_new_blog', array($this, 'mu_handler'));
|
251 |
+
add_action('archive_blog', array($this, 'mu_handler'));
|
252 |
+
add_action('unarchive_blog', array( $this, 'mu_handler'));
|
253 |
+
add_action('activate_blog', array($this, 'mu_handler'));
|
254 |
+
add_action('deactivate_blog', array($this, 'mu_handler'));
|
255 |
+
add_action('wp_delete_site', array($this, 'mu_delete_handler'));
|
256 |
+
|
257 |
+
/* SENSORS USER ACTIONS AT FRONTEND */
|
258 |
+
add_action('wp_login', array($this, 'user_login_handler'), 10, 2);
|
259 |
+
add_action('wp_logout', array( $this, 'user_logout_handler'), 5, 1);
|
260 |
+
add_action('password_reset', array( $this, 'password_reset_handler'), 10, 2);
|
261 |
+
}
|
262 |
+
}
|
263 |
+
endif;
|
wp_site_info.php
CHANGED
@@ -39,6 +39,12 @@ class BVWPSiteInfo {
|
|
39 |
return is_main_site();
|
40 |
}
|
41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
public function info() {
|
43 |
$info = array();
|
44 |
$this->basic($info);
|
39 |
return is_main_site();
|
40 |
}
|
41 |
|
42 |
+
public function getMainSiteId() {
|
43 |
+
if (!function_exists('get_main_site_id'))
|
44 |
+
return 0;
|
45 |
+
return get_main_site_id();
|
46 |
+
}
|
47 |
+
|
48 |
public function info() {
|
49 |
$info = array();
|
50 |
$this->basic($info);
|