The WP Remote WordPress Plugin - Version 4.54

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 Icon 128x128 The WP Remote WordPress Plugin
Version 4.54
Comparing to
See all releases

Code changes from version 4.36 to 4.54

account.php CHANGED
@@ -84,6 +84,39 @@ if (!class_exists('WPRAccount')) :
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('WPRAccount')) :
155
  $this->settings->updateOption('bvLastRecvTime', $time);
156
  return 1;
157
  }
158
-
159
  public function updateInfo($info) {
160
  $accounts = self::allAccounts($this->settings);
161
- $plugname = self::getPlugName($this->settings);
 
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('WPRAccount')) :
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 = WPRAccount::accountsByType($settings, $account_type);
224
+ if (sizeof($accounts) >= 1) {
225
+ foreach ($accounts as $pubkey => $value) {
226
+ WPRAccount::remove($settings, $pubkey);
227
+ }
228
+ return true;
229
+ }
230
+ return false;
231
+ }
232
+
233
+ public static function removeByAccountGid($settings, $account_gid) {
234
+ $accounts = WPRAccount::accountsByGid($settings, $account_gid);
235
+ if (sizeof($accounts) >= 1) {
236
+ foreach ($accounts as $pubkey => $value) {
237
+ WPRAccount::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);
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" => WPRAccount::remove($this->settings, $params['public']));
25
  break;
26
  case "updt":
27
- $info = array();
28
- $info['email'] = $params['email'];
29
- $info['url'] = $params['url'];
30
- $info['pubkey'] = $params['pubkey'];
31
- $account->updateInfo($info);
32
  $resp = array("status" => WPRAccount::exists($this->settings, $params['pubkey']));
33
  break;
34
  case "updtapikey":
35
  WPRAccount::updateApiPublicKey($this->settings, $params['pubkey']);
36
  $resp = array("status" => $this->settings->getOption(WPRAccount::$api_public_key));
37
  break;
38
- case "rmdefsec":
39
- $resp = array("status" => $settings->deleteOption('bvDefaultSecret'));
40
  break;
41
  case "rmbvkeys":
42
  $resp = array("status" => $settings->deleteOption('bvKeys'));
24
  $resp = array("status" => WPRAccount::remove($this->settings, $params['public']));
25
  break;
26
  case "updt":
27
+ $account->updateInfo($params);
 
 
 
 
28
  $resp = array("status" => WPRAccount::exists($this->settings, $params['pubkey']));
29
  break;
30
  case "updtapikey":
31
  WPRAccount::updateApiPublicKey($this->settings, $params['pubkey']);
32
  $resp = array("status" => $this->settings->getOption(WPRAccount::$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
- $data["md5"] = md5(serialize($rows));
 
 
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 WPRInfo($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 WPRInfo($callback_handler->settings);
18
+ $this->bvapi = new WPRWPAPI($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('WPRInfo')) :
5
  class WPRInfo {
6
  public $settings;
 
7
  public $plugname = 'wpremote';
8
  public $brandname = 'WP Remote';
9
  public $badgeinfo = 'wprbadge';
10
  public $ip_header_option = 'wpripheader';
11
  public $brand_option = 'wprbrand';
12
- public $version = '4.36';
13
  public $webpage = 'https://wpremote.com';
14
  public $appurl = 'https://app.wpremote.com';
15
  public $slug = 'wpremote/plugin.php';
16
  public $plug_redirect = 'wprredirect';
17
  public $logo = '../img/wprlogo.png';
18
  public $brand_icon = '/img/icon.png';
 
19
 
20
  public function __construct($settings) {
21
  $this->settings = $settings;
 
22
  }
23
 
24
- public function isManualSignup() {
25
- $scanOption = $this->settings->getOption('bvmanualsignup');
26
- return (isset($scanOption) && $scanOption == 1);
 
 
 
 
 
 
 
 
 
 
27
  }
28
 
29
  public function getBrandInfo() {
@@ -79,6 +92,14 @@ if (!class_exists('WPRInfo')) :
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('WPRInfo')) :
5
  class WPRInfo {
6
  public $settings;
7
+ public $config;
8
  public $plugname = 'wpremote';
9
  public $brandname = 'WP Remote';
10
  public $badgeinfo = 'wprbadge';
11
  public $ip_header_option = 'wpripheader';
12
  public $brand_option = 'wprbrand';
13
+ public $version = '4.54';
14
  public $webpage = 'https://wpremote.com';
15
  public $appurl = 'https://app.wpremote.com';
16
  public $slug = 'wpremote/plugin.php';
17
  public $plug_redirect = 'wprredirect';
18
  public $logo = '../img/wprlogo.png';
19
  public $brand_icon = '/img/icon.png';
20
+ public $services_option_name = 'wprconfig';
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 (WPRWPSiteInfo::isCWServer()) {
29
+
30
+ $bot_protect_accounts = WPRAccount::accountsByType($this->settings, 'botprotect');
31
+ if (sizeof($bot_protect_accounts) >= 1)
32
+ return true;
33
+
34
+ $bot_protect_accounts = WPRAccount::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
  }
plugin.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: https://wpremote.com
5
  Description: Manage your WordPress site with <a href="https://wpremote.com/">WP Remote</a>.
6
  Author: WP Remote
7
  Author URI: https://wpremote.com
8
- Version: 4.36
9
  Network: True
10
  */
11
 
@@ -77,6 +77,7 @@ if (is_admin()) {
77
  add_action('admin_head', array($wpadmin, 'removeAdminNotices'), 3);
78
  add_action('admin_notices', array($wpadmin, 'activateWarning'));
79
  ##ADMINENQUEUESCRIPTS##
 
80
  }
81
 
82
 
@@ -138,10 +139,13 @@ if ((array_key_exists('bvplugname', $_REQUEST)) && ($_REQUEST['bvplugname'] == "
138
  $response->terminate($resp);
139
  }
140
  } else {
141
- if ($bvinfo->isProtectModuleEnabled()) {
142
  require_once dirname( __FILE__ ) . '/protect/wp/protect.php';
143
  $bvprotect = new BVProtect($bvdb, $bvsettings);
144
- $bvprotect->run();
 
 
 
145
  }
146
 
147
  if ($bvinfo->isDynSyncModuleEnabled()) {
@@ -150,6 +154,13 @@ if ((array_key_exists('bvplugname', $_REQUEST)) && ($_REQUEST['bvplugname'] == "
150
  $dynsync->init();
151
  }
152
 
 
 
 
 
 
 
 
153
  $bv_site_settings = $bvsettings->getOption('bv_site_settings');
154
  if (isset($bv_site_settings)) {
155
  if (isset($bv_site_settings['wp_auto_updates'])) {
5
  Description: Manage your WordPress site with <a href="https://wpremote.com/">WP Remote</a>.
6
  Author: WP Remote
7
  Author URI: https://wpremote.com
8
+ Version: 4.54
9
  Network: True
10
  */
11
 
77
  add_action('admin_head', array($wpadmin, 'removeAdminNotices'), 3);
78
  add_action('admin_notices', array($wpadmin, 'activateWarning'));
79
  ##ADMINENQUEUESCRIPTS##
80
+ ##REMOVEDEACTIVATIONLINK##
81
  }
82
 
83
 
139
  $response->terminate($resp);
140
  }
141
  } else {
142
+ if ($bvsettings->getOption('bvptplug') === $bvinfo->plugname) {
143
  require_once dirname( __FILE__ ) . '/protect/wp/protect.php';
144
  $bvprotect = new BVProtect($bvdb, $bvsettings);
145
+ $bvprotect->init();
146
+ if ($bvinfo->isActivePlugin() && !(defined( 'WP_CLI' ) && WP_CLI)) {
147
+ $bvprotect->run();
148
+ }
149
  }
150
 
151
  if ($bvinfo->isDynSyncModuleEnabled()) {
154
  $dynsync->init();
155
  }
156
 
157
+ if ($bvinfo->isServiceActive('activity_log')) {
158
+ require_once dirname( __FILE__ ) . '/wp_actlog.php';
159
+ $bvconfig = $bvinfo->config;
160
+ $actlog = new BVWPActLog($bvdb, $bvsettings, $bvinfo, $bvconfig['activity_log']);
161
+ $actlog->init();
162
+ }
163
+
164
  $bv_site_settings = $bvsettings->getOption('bv_site_settings');
165
  if (isset($bv_site_settings)) {
166
  if (isset($bv_site_settings['wp_auto_updates'])) {
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
- #Valid mc_data filenames
82
- public static $validMcDataFilenames = array('mc.conf', 'mc_ips.conf');
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->getBody('action')),
212
  true, 'BODY[');
213
  }
214
- $result += $this->profileRequestInfo($this->request->getBody(),
215
  $this->config->isReqProfilingModeDebug(), 'BODY[');
216
- $result += $this->profileRequestInfo($this->request->getQueryString(),
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) >= 2) {
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 $queryString;
15
  private $timestamp;
16
  private $uri;
17
- private $body;
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 = 1;
31
- const WHITELISTED = 2;
32
- const NORMAL = 3;
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->setQueryString($_GET);
48
  $this->setCookies($_COOKIE);
49
- $this->setBody($_POST);
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 setBody($body) {
107
- $this->body = $body;
108
  }
109
 
110
  public function setCookies($cookies) {
@@ -143,8 +143,8 @@ class BVWPRequest {
143
  $this->path = $path;
144
  }
145
 
146
- public function setQueryString($queryString) {
147
- $this->queryString = $queryString;
148
  }
149
 
150
  public function setTimestamp($timestamp) {
@@ -155,8 +155,10 @@ class BVWPRequest {
155
  $this->uri = $uri;
156
  }
157
 
158
- public function updateRulesInfo($key, $value) {
159
- $this->rulesInfo[$key] = $value;
 
 
160
  }
161
 
162
  public function getRulesInfo() {
@@ -227,15 +229,15 @@ class BVWPRequest {
227
  }
228
  return null;
229
  }
230
-
231
- public function getBody() {
232
  if (func_num_args() > 0) {
233
  $args = func_get_args();
234
- return $this->getKeyVal($this->body, $args);
235
  }
236
- return $this->body;
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 getQueryString() {
248
  if (func_num_args() > 0) {
249
  $args = func_get_args();
250
- return $this->getKeyVal($this->queryString, $args);
251
  }
252
- return $this->queryString;
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->isBlacklistedIP()) {
 
 
187
  $this->setCategory(BVWPLP::BLACKLISTED);
188
  $this->terminateLogin();
189
- } else if ($this->isKnownLogin() || $this->isWhitelistedIP()) {
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
- $fw = new BVFW($fwLogger, $fwConfHash, $ip, $bvinfo, $bvipstore);
 
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.wpremote.com/home/signup
6
  Requires at least: 4.0
7
  Tested up to: 5.6
8
  Requires PHP: 5.4.0
9
- Stable tag: 4.36
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
 
@@ -32,6 +32,11 @@ You can email us at support@wpremote.com for support.
32
  3. Sign up for an account at wpremote.com and add your site.
33
 
34
  == CHANGELOG ==
 
 
 
 
 
35
 
36
  = 4.36 =
37
  * Block WordPress auto update feature
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
 
32
  3. Sign up for an account at wpremote.com and add your site.
33
 
34
  == CHANGELOG ==
35
+ = 4.54 =
36
+ * Added Support For Multi Table Callbacks
37
+ * Added Firewall Rule Evaluator
38
+ * Added Activity Logs feature
39
+ * Minor Improvements
40
 
41
  = 4.36 =
42
  * Block WordPress auto update feature
wp_actions.php CHANGED
@@ -38,7 +38,7 @@ if (!class_exists('WPRWPAction')) :
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() {
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 = WPRAccount::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 WPRWPSiteInfo {
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);