MalCare WordPress Security Plugin – Malware Scanner, Cleaner, Security Firewall - Version 4.2

Version Description

  • Robust write callbacks
  • Improved and Robust prepend in Firewall Support
  • Without FTP cleanup and restore support
Download this release

Release Info

Developer ritesh.soni36
Plugin Icon 128x128 MalCare WordPress Security Plugin – Malware Scanner, Cleaner, Security Firewall
Version 4.2
Comparing to
See all releases

Code changes from version 3.8 to 4.2

account.php CHANGED
@@ -42,6 +42,10 @@ if (!class_exists('MCAccount')) :
42
  return $str;
43
  }
44
 
 
 
 
 
45
  public static function apiPublicAccount($settings) {
46
  $pubkey = $settings->getOption(self::$api_public_key);
47
  return self::find($settings, $pubkey);
@@ -179,4 +183,4 @@ if (!class_exists('MCAccount')) :
179
  return array_key_exists($pubkey, $accounts);
180
  }
181
  }
182
- endif;
42
  return $str;
43
  }
44
 
45
+ public static function sanitizeKey($key) {
46
+ return preg_replace('/[^a-zA-Z0-9_\-]/', '', $key);
47
+ }
48
+
49
  public static function apiPublicAccount($settings) {
50
  $pubkey = $settings->getOption(self::$api_public_key);
51
  return self::find($settings, $pubkey);
183
  return array_key_exists($pubkey, $accounts);
184
  }
185
  }
186
+ endif;
callback/handler.php CHANGED
@@ -84,6 +84,10 @@ if (!class_exists('BVCallbackHandler')) :
84
  require_once dirname( __FILE__ ) . '/wings/account.php';
85
  $module = new BVAccountCallback($this);
86
  break;
 
 
 
 
87
  default:
88
  require_once dirname( __FILE__ ) . '/wings/misc.php';
89
  $module = new BVMiscCallback($this);
@@ -104,4 +108,4 @@ if (!class_exists('BVCallbackHandler')) :
104
  return 1;
105
  }
106
  }
107
- endif;
84
  require_once dirname( __FILE__ ) . '/wings/account.php';
85
  $module = new BVAccountCallback($this);
86
  break;
87
+ case 'fswrt':
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);
108
  return 1;
109
  }
110
  }
111
+ endif;
callback/request.php CHANGED
@@ -89,7 +89,7 @@ if (!class_exists('BVCallbackRequest')) :
89
  if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms']) &&
90
  array_key_exists('bvprmsmac', $in_params) && isset($in_params['bvprmsmac'])) {
91
  $digest_algo = 'SHA1';
92
- $sent_mac = $in_params['bvprmsmac'];
93
 
94
  if (array_key_exists('bvprmshshalgo', $in_params) && isset($in_params['bvprmshshalgo'])) {
95
  $digest_algo = $in_params['bvprmshshalgo'];
@@ -176,4 +176,4 @@ if (!class_exists('BVCallbackRequest')) :
176
  return $data;
177
  }
178
  }
179
- endif;
89
  if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms']) &&
90
  array_key_exists('bvprmsmac', $in_params) && isset($in_params['bvprmsmac'])) {
91
  $digest_algo = 'SHA1';
92
+ $sent_mac = MCAccount::sanitizeKey($in_params['bvprmsmac']);
93
 
94
  if (array_key_exists('bvprmshshalgo', $in_params) && isset($in_params['bvprmshshalgo'])) {
95
  $digest_algo = $in_params['bvprmshshalgo'];
176
  return $data;
177
  }
178
  }
179
+ endif;
callback/wings/fs.php CHANGED
@@ -12,8 +12,6 @@ class BVFSCallback extends BVCallbackBase {
12
 
13
  public function __construct($callback_handler) {
14
  $this->account = $callback_handler->account;
15
- $this->siteinfo = $callback_handler->siteinfo;
16
- $this->bvinfo = $callback_handler->bvinfo;
17
  }
18
 
19
  function fileStat($relfile) {
@@ -236,53 +234,11 @@ class BVFSCallback extends BVCallbackBase {
236
  return $result;
237
  }
238
 
239
- function mkdir($path, $permissions) {
240
- $result = array();
241
- $path = ABSPATH.$path;
242
-
243
- if (!file_exists($path)) {
244
- if (!mkdir($path)) {
245
- $result['status'] = 'Error';
246
- $result['message'] = 'UNABLE_TO_CREATE_DIR';
247
- }
248
- } else {
249
- $result['already_exists'] = true;
250
- }
251
-
252
- if (file_exists($path)) {
253
- $result['exists'] = true;
254
-
255
- if (chmod($path, $permissions)) {
256
- $result['status'] = 'Done';
257
- } else {
258
- $result['status'] = 'Error';
259
- $result['message'] = "UNABLE_TO_SET_PERMISSIONS";
260
- }
261
- }
262
-
263
- return $result;
264
- }
265
-
266
  function process($request) {
267
  $params = $request->params;
268
  $stream_init_info = BVStream::startStream($this->account, $request);
269
 
270
- if(MCWPSiteInfo::isCWServer() && !$this->bvinfo->canOverrideCW()) {
271
- if(array_key_exists('initdir', $params)) {
272
- return $stream_init_info;
273
- }
274
-
275
- if (array_key_exists('files', $params)) {
276
- $files = $params['files'];
277
-
278
- foreach($files as $file) {
279
- if (!in_array($file, BVFSCallback::$cwAllowedFiles)) {
280
- return $stream_init_info;
281
- }
282
- }
283
- }
284
- }
285
-
286
 
287
  if (array_key_exists('stream', $stream_init_info)) {
288
  $this->stream = $stream_init_info['stream'];
@@ -361,10 +317,6 @@ class BVFSCallback extends BVCallbackBase {
361
  $withContent = array_key_exists('withcontent', $params) ? $params['withcontent'] : true;
362
  $resp = array("files_content" => $this->getFilesContent($files, $withContent));
363
  break;
364
- case "mkdr":
365
- $permissions = array_key_exists('permissions', $params) ? $params['permissions'] : 0777;
366
- $resp = array('mkdir' => $this->mkdir($params['path'], $permissions));
367
- break;
368
  default:
369
  $resp = false;
370
  }
12
 
13
  public function __construct($callback_handler) {
14
  $this->account = $callback_handler->account;
 
 
15
  }
16
 
17
  function fileStat($relfile) {
234
  return $result;
235
  }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  function process($request) {
238
  $params = $request->params;
239
  $stream_init_info = BVStream::startStream($this->account, $request);
240
 
241
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
  if (array_key_exists('stream', $stream_init_info)) {
244
  $this->stream = $stream_init_info['stream'];
317
  $withContent = array_key_exists('withcontent', $params) ? $params['withcontent'] : true;
318
  $resp = array("files_content" => $this->getFilesContent($files, $withContent));
319
  break;
 
 
 
 
320
  default:
321
  $resp = false;
322
  }
callback/wings/fs_write.php ADDED
@@ -0,0 +1,453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')) exit;
4
+ if (!class_exists('BVFSWriteCallback')) :
5
+
6
+ class BVFSWriteCallback extends BVCallbackBase {
7
+
8
+ const MEGABYTE = 1024 * 1024;
9
+
10
+ public function __construct() {
11
+ }
12
+
13
+ public function removeFiles($files) {
14
+ $result = array();
15
+
16
+ foreach($files as $file) {
17
+ $file_result = array();
18
+
19
+ if (file_exists($file)) {
20
+
21
+ $file_result['status'] = unlink($file);
22
+ if ($file_result['status'] === false) {
23
+ $file_result['error'] = "UNLINK_FAILED";
24
+ }
25
+
26
+ } else {
27
+ $file_result['status'] = true;
28
+ $file_result['error'] = "NOT_PRESENT";
29
+ }
30
+
31
+ $result[$file] = $file_result;
32
+ }
33
+
34
+ $result['status'] = true;
35
+ return $result;
36
+ }
37
+
38
+ public function makeDirs($dirs) {
39
+ $result = array();
40
+
41
+ foreach($dirs as $dir) {
42
+ $dir_result = array();
43
+
44
+ if (file_exists($dir)) {
45
+
46
+ if (is_dir($dir)) {
47
+ $dir_result['status'] = true;
48
+ $dir_result['message'] = "DIR_ALREADY_PRESENT";
49
+ } else {
50
+ $dir_result['status'] = false;
51
+ $dir_result['error'] = "FILE_PRESENT_IN_PLACE_OF_DIR";
52
+ }
53
+
54
+ } else {
55
+
56
+ $dir_result['status'] = mkdir($dir);
57
+ if ($dir_result['status'] === false) {
58
+ $dir_result['error'] = "MKDIR_FAILED";
59
+ }
60
+
61
+ }
62
+
63
+ $result[$dir] = $dir_result;
64
+ }
65
+
66
+ $result['status'] = true;
67
+ return $result;
68
+ }
69
+
70
+ public function removeDirs($dirs) {
71
+ $result = array();
72
+
73
+ foreach($dirs as $dir) {
74
+ $dir_result = array();
75
+
76
+ if (is_dir($dir) && !is_link($dir)) {
77
+
78
+ if ($this->isEmptyDir($dir)) {
79
+
80
+ $dir_result['status'] = rmdir($dir);
81
+ if ($dir_result['status'] === false) {
82
+ $dir_result['error'] = "RMDIR_FAILED";
83
+ }
84
+
85
+ } else {
86
+ $dir_result['status'] = false;
87
+ $dir_result['error'] = "NOT_EMPTY";
88
+ }
89
+
90
+ } else {
91
+ $dir_result['status'] = false;
92
+ $dir_result['error'] = "NOT_DIR";
93
+ }
94
+
95
+ $result[$dir] = $dir_result;
96
+ }
97
+
98
+ $result['status'] = true;
99
+ return $result;
100
+ }
101
+
102
+ public function isEmptyDir($dir) {
103
+ $handle = opendir($dir);
104
+
105
+ while (false !== ($entry = readdir($handle))) {
106
+ if ($entry != "." && $entry != "..") {
107
+ closedir($handle);
108
+ return false;
109
+ }
110
+ }
111
+ closedir($handle);
112
+
113
+ return true;
114
+ }
115
+
116
+ public function doChmod($path_infos) {
117
+ $result = array();
118
+
119
+ foreach($path_infos as $path => $mode) {
120
+ $path_result = array();
121
+
122
+ if (file_exists($path)) {
123
+
124
+ $path_result['status'] = chmod($path, $mode);
125
+ if ($path_result['status'] === false) {
126
+ $path_result['error'] = "CHMOD_FAILED";
127
+ }
128
+
129
+ } else {
130
+ $path_result['status'] = false;
131
+ $path_result['error'] = "NOT_FOUND";
132
+ }
133
+
134
+ $result[$path] = $path_result;
135
+ }
136
+
137
+ $result['status'] = true;
138
+ return $result;
139
+ }
140
+
141
+ public function concatFiles($ifiles, $ofile, $bsize, $offset) {
142
+ if (($offset !== 0) && (!file_exists($ofile))) {
143
+ return array(
144
+ 'status' => false,
145
+ 'error' => 'OFILE_NOT_FOUND_BEFORE_CONCAT'
146
+ );
147
+ }
148
+
149
+ if (file_exists($ofile) && ($offset !== 0)) {
150
+ $handle = fopen($ofile, 'rb+');
151
+ } else {
152
+ $handle = fopen($ofile, 'wb+');
153
+ }
154
+
155
+ if ($handle === false) {
156
+ return array(
157
+ 'status' => false,
158
+ 'error' => 'FOPEN_FAILED'
159
+ );
160
+ }
161
+
162
+ if ($offset !== 0) {
163
+ if (fseek($handle, $offset, SEEK_SET) === -1) {
164
+ return array(
165
+ 'status' => false,
166
+ 'error' => 'FSEEK_FAILED'
167
+ );
168
+ }
169
+ }
170
+
171
+ $total_written = 0;
172
+ foreach($ifiles as $file) {
173
+ $fp = fopen($file, 'rb');
174
+ if ($fp === false) {
175
+ return array(
176
+ 'status' => false,
177
+ 'error' => "UNABLE_TO_OPEN_TMP_OFILE_FOR_READING"
178
+ );
179
+ }
180
+
181
+ while (!feof($fp)) {
182
+ $content = fread($fp, $bsize);
183
+ if ($content === false) {
184
+ return array(
185
+ 'status' => false,
186
+ 'error' => "UNABLE_TO_READ_INFILE",
187
+ 'filename' => $file
188
+ );
189
+ }
190
+
191
+ $written = fwrite($handle, $content);
192
+ if ($written === false) {
193
+ return array(
194
+ 'status' => false,
195
+ 'error' => "UNABLE_TO_WRITE_TO_OFILE",
196
+ 'filename' => $file
197
+ );
198
+ }
199
+ $total_written += $written;
200
+ }
201
+
202
+ fclose($fp);
203
+ }
204
+
205
+ $result = array();
206
+ $result['fclose'] = fclose($handle);
207
+
208
+ if (file_exists($ofile) && ($total_written != 0)) {
209
+ $result['status'] = true;
210
+ $result['fsize'] = filesize($ofile);
211
+ $result['total_written'] = $total_written;
212
+ } else {
213
+ $result['status'] = false;
214
+ $result['error'] = 'CONCATINATED_FILE_FAILED';
215
+ }
216
+
217
+ return $result;
218
+ }
219
+
220
+ public function renameFiles($path_infos) {
221
+ $result = array();
222
+
223
+ foreach($path_infos as $oldpath => $newpath) {
224
+ $action_result = array();
225
+ $failed = array();
226
+
227
+ if (file_exists($oldpath)) {
228
+
229
+ $action_result['status'] = rename($oldpath, $newpath);
230
+ if ($action_result['status'] === false) {
231
+ $action_result['error'] = "RENAME_FAILED";
232
+ }
233
+
234
+ } else {
235
+ $action_result['status'] = false;
236
+ $action_result['error'] = "NOT_FOUND";
237
+ }
238
+
239
+ $result[$oldpath] = $action_result;
240
+ }
241
+
242
+ $result['status'] = true;
243
+ return $result;
244
+ }
245
+
246
+ public function curlFile($ifile_url, $ofile, $timeout) {
247
+ $fp = fopen($ofile, "wb+");
248
+ if ($fp === false) {
249
+ return array(
250
+ 'error' => 'FOPEN_FAILED_FOR_TEMP_OFILE'
251
+ );
252
+ }
253
+
254
+ $result = array();
255
+ $ch = curl_init($ifile_url);
256
+ curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
257
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
258
+ curl_setopt($ch, CURLOPT_HEADER, 0);
259
+ curl_setopt($ch, CURLOPT_FILE, $fp);
260
+
261
+ if (!curl_exec($ch)) {
262
+ $result['error'] = curl_error($ch);
263
+ $result['errorno'] = curl_errno($ch);
264
+ }
265
+
266
+ curl_close($ch);
267
+ fclose($fp);
268
+
269
+ return $result;
270
+ }
271
+
272
+ public function wgetFile($ifile_url, $ofile) {
273
+ $result = array();
274
+ system("wget -nv -O $ofile $ifile_url 2>&1 > /dev/null", $retval);
275
+
276
+ if ($retval !== 0) {
277
+ $result['error'] = "WGET_ERROR";
278
+ }
279
+
280
+ return $result;
281
+ }
282
+
283
+ public function streamCopyFile($ifile_url, $ofile) {
284
+ $result = array();
285
+ $handle = fopen($ifile_url, "rb");
286
+
287
+ if ($handle === false) {
288
+ return array(
289
+ 'error' => "UNABLE_TO_OPEN_REMOTE_FILE_STREAM"
290
+ );
291
+ }
292
+
293
+ $fp = fopen($ofile, "wb+");
294
+ if ($fp === false) {
295
+ fclose($handle);
296
+
297
+ return array(
298
+ 'error' => 'FOPEN_FAILED_FOR_OFILE'
299
+ );
300
+ }
301
+
302
+ if (stream_copy_to_stream($handle, $fp) === false) {
303
+ $result['error'] = "UNABLE_TO_WRITE_TO_TMP_OFILE";
304
+ }
305
+
306
+ fclose($handle);
307
+ fclose($fp);
308
+
309
+ return $result;
310
+ }
311
+
312
+ public function writeContentToFile($content, $ofile) {
313
+ $result = array();
314
+
315
+ $fp = fopen($ofile, "wb+");
316
+ if ($fp === false) {
317
+ return array(
318
+ 'error' => 'FOPEN_FAILED_FOR_TEMP_OFILE'
319
+ );
320
+ }
321
+
322
+ if (fwrite($fp, $content) === false) {
323
+ $resp['error'] = "UNABLE_TO_WRITE_TO_TMP_OFILE";
324
+ }
325
+ fclose($fp);
326
+
327
+ return $result;
328
+ }
329
+
330
+ public function moveUploadedFile($ofile) {
331
+ $result = array();
332
+
333
+ if (isset($_FILES['myfile'])) {
334
+ $myfile = $_FILES['myfile'];
335
+ $is_upload_ok = false;
336
+
337
+ switch ($myfile['error']) {
338
+ case UPLOAD_ERR_OK:
339
+ $is_upload_ok = true;
340
+ break;
341
+ case UPLOAD_ERR_NO_FILE:
342
+ $result['error'] = "UPLOADERR_NO_FILE";
343
+ break;
344
+ case UPLOAD_ERR_INI_SIZE:
345
+ case UPLOAD_ERR_FORM_SIZE:
346
+ $result['error'] = "UPLOADERR_FORM_SIZE";
347
+ break;
348
+ default:
349
+ $result['error'] = "UPLOAD_ERR_UNKNOWN";
350
+ }
351
+
352
+ if ($is_upload_ok && !isset($myfile['tmp_name'])) {
353
+ $result['error'] = "MYFILE_TMP_NAME_NOT_FOUND";
354
+ $is_upload_ok = false;
355
+ }
356
+
357
+ if ($is_upload_ok) {
358
+ if (move_uploaded_file($myfile['tmp_name'], $ofile) === false) {
359
+ $result['error'] = 'MOVE_UPLOAD_FILE_FAILED';
360
+ }
361
+ }
362
+
363
+ } else {
364
+ $result['error'] = "FILE_NOT_PRESENT_IN_FILES";
365
+ }
366
+
367
+ return $result;
368
+ }
369
+
370
+
371
+ public function uploadFile($params) {
372
+ $resp = array();
373
+ $ofile = $params['ofile'];
374
+
375
+ switch($params['protocol']) {
376
+ case "curl":
377
+ $timeout = isset($params['timeout']) ? $params['timeout'] : 60;
378
+ $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
379
+
380
+ $resp = $this->curlFile($ifile_url, $ofile, $timeout);
381
+ break;
382
+ case "wget":
383
+ $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
384
+
385
+ $resp = $this->wgetFile($ifile_url, $ofile);
386
+ break;
387
+ case "streamcopy":
388
+ $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
389
+
390
+ $resp = $this->streamCopyFile($ifile_url, $ofile);
391
+ break;
392
+ case "httpcontenttransfer":
393
+ $resp = $this->writeContentToFile($params['content'], $ofile);
394
+ break;
395
+ case "httpfiletransfer":
396
+ $resp = $this->moveUploadedFile($ofile);
397
+ break;
398
+ default:
399
+ $resp['error'] = "INVALID_PROTOCOL";
400
+ }
401
+
402
+ if (isset($resp['error'])) {
403
+ $resp['status'] = false;
404
+ } else {
405
+
406
+ if (file_exists($ofile)) {
407
+ $resp['status'] = true;
408
+ $resp['fsize'] = filesize($ofile);
409
+ } else {
410
+ $resp['status'] = false;
411
+ $resp['error'] = "OFILE_NOT_FOUND";
412
+ }
413
+
414
+ }
415
+
416
+ return $resp;
417
+ }
418
+
419
+ public function process($request) {
420
+ $params = $request->params;
421
+
422
+ switch ($request->method) {
423
+ case "rmfle":
424
+ $resp = $this->removeFiles($params['files']);
425
+ break;
426
+ case "chmd":
427
+ $resp = $this->doChmod($params['pathinfos']);
428
+ break;
429
+ case "mkdr":
430
+ $resp = $this->makeDirs($params['dirs']);
431
+ break;
432
+ case "rmdr":
433
+ $resp = $this->removeDirs($params['dirs']);
434
+ break;
435
+ case "renmefle":
436
+ $resp = $this->renameFiles($params['pathinfos']);
437
+ break;
438
+ case "wrtfle":
439
+ $resp = $this->uploadFile($params);
440
+ break;
441
+ case "cncatfls":
442
+ $bsize = (isset($params['bsize'])) ? $params['bsize'] : (8 * BVFSWriteCallback::MEGABYTE);
443
+ $offset = (isset($params['offset'])) ? $params['offset'] : 0;
444
+ $resp = $this->concatFiles($params['infiles'], $params['ofile'], $bsize, $offset);
445
+ break;
446
+ default:
447
+ $resp = false;
448
+ }
449
+
450
+ return $resp;
451
+ }
452
+ }
453
+ endif;
callback/wings/info.php CHANGED
@@ -136,6 +136,7 @@ class BVInfoCallback extends BVCallbackBase {
136
  'wpversion' => $wp_version,
137
  'dbversion' => $wp_db_version,
138
  'abspath' => ABSPATH,
 
139
  'uploadpath' => $upload_dir['basedir'],
140
  'uploaddir' => wp_upload_dir(),
141
  'contentdir' => defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : null,
@@ -237,6 +238,15 @@ class BVInfoCallback extends BVCallbackBase {
237
  return array('actinfo' => $resp);
238
  }
239
 
 
 
 
 
 
 
 
 
 
240
  public function process($request) {
241
  $db = $this->db;
242
  $params = $request->params;
@@ -290,6 +300,19 @@ class BVInfoCallback extends BVCallbackBase {
290
  $transient = $this->objectToArray($transient);
291
  $resp = array("transient" => $transient);
292
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  default:
294
  $resp = false;
295
  }
136
  'wpversion' => $wp_version,
137
  'dbversion' => $wp_db_version,
138
  'abspath' => ABSPATH,
139
+ 'bvpluginpath' => defined('MCBASEPATH') ? MCBASEPATH : null,
140
  'uploadpath' => $upload_dir['basedir'],
141
  'uploaddir' => wp_upload_dir(),
142
  'contentdir' => defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : null,
238
  return array('actinfo' => $resp);
239
  }
240
 
241
+ public function getHostInfo() {
242
+ $host_info = $_SERVER;
243
+ $host_info['PHP_SERVER_NAME'] = php_uname('\n');
244
+ if (array_key_exists('IS_PRESSABLE', get_defined_constants())) {
245
+ $host_info['IS_PRESSABLE'] = true;
246
+ }
247
+ return array('host_info' => $host_info);
248
+ }
249
+
250
  public function process($request) {
251
  $db = $this->db;
252
  $params = $request->params;
300
  $transient = $this->objectToArray($transient);
301
  $resp = array("transient" => $transient);
302
  break;
303
+ case "gthost":
304
+ $resp = $this->getHostInfo();
305
+ break;
306
+ case "gtplinfo":
307
+ $args = array(
308
+ 'slug' => wp_unslash($params['slug'])
309
+ );
310
+ $action = $params['action'];
311
+ $args = (object) $args;
312
+ $args = apply_filters('plugins_api_args', $args, $action);
313
+ $data = apply_filters('plugins_api', false, $action, $args);
314
+ $resp = array("plugins_info" => $data);
315
+ break;
316
  default:
317
  $resp = false;
318
  }
callback/wings/protect.php CHANGED
@@ -16,313 +16,6 @@ class BVProtectCallback extends BVCallbackBase {
16
  $this->settings = $callback_handler->settings;
17
  }
18
 
19
- public function contentDir() {
20
- return defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : "";
21
- }
22
-
23
- public function mcDataPath() {
24
- return $this->contentDir() . '/mc_data/';
25
- }
26
-
27
- public function mcIPsFilePath($confkey) {
28
- return $this->mcDataPath() . $confkey. '-mc_ips.conf';
29
- }
30
-
31
- public function mcConfigFilePath($confkey) {
32
- return $this->mcDataPath() . $confkey. '-mc.conf';
33
- }
34
-
35
- public function mcLogFilePath($confkey) {
36
- return $this->mcDataPath() . $confkey. '-mc.log';
37
- }
38
-
39
- public function mcWAFFilePath() {
40
- return ABSPATH . 'malcare-waf.php';
41
- }
42
-
43
- public function htAccessFilePath() {
44
- return ABSPATH . '.htaccess';
45
- }
46
-
47
- public function useriniFilePath() {
48
- return ABSPATH . '.user.ini';
49
- }
50
-
51
- public function writeToFile($file, $content, $permissions) {
52
- $tmp_file = tmpfile();
53
- $result = array();
54
-
55
- if (!$tmp_file) {
56
- $result = array('status' => 'Error', 'message' => 'UNABLE_TO_CREATE_TMPFILE');
57
- } else {
58
- $tmpmeta = stream_get_meta_data($tmp_file);
59
- $tmpfilename = $tmpmeta['uri'];
60
-
61
- if (file_put_contents($tmpfilename, $content)) {
62
-
63
- $tmp_contents = file_get_contents($tmpfilename);
64
-
65
- if ($tmp_contents !== $content) {
66
- $result = array('status' => 'Error', 'message' => 'TMPFILE_CONTENT_MISMATCH');
67
- } else if (!@rename($tmpfilename, $file)) {
68
- $result = array('status' => 'Error', 'message' => 'UNABLE_TO_RENAME_TMPFILE');
69
- } else {
70
- chmod($file, $permissions);
71
- $fcontent = file_get_contents($file);
72
-
73
- if ($fcontent !== $content) {
74
- $result = array(
75
- 'status' => 'Error',
76
- 'message' => 'FILE_NOT_WRITTEN_PROPERLY',
77
- 'content' => $fcontent
78
- );
79
- } else {
80
- $result = array('status' => 'Done');
81
- }
82
-
83
- }
84
- } else {
85
- $result = array('status' => 'Error', 'message' => 'UNABLE_TO_WRITE_IN_TMPFILE');
86
- }
87
- }
88
- return $result;
89
- }
90
-
91
- public function writeToMcDataFile($fname, $content, $confkey, $permissions) {
92
- $result = array();
93
- if (in_array($fname, BVFWConfig::$validMcDataFilenames)) {
94
-
95
- $mcDataPath = $this->mcDataPath();
96
-
97
- if (file_exists($mcDataPath)) {
98
- $filepath = $mcDataPath . $confkey . '-' . $fname;
99
- $result = $this->writeToFile($filepath, $content, $permissions);
100
- } else {
101
- $result['status'] = 'Error';
102
- $result['message'] = 'MC_DATA_PATH_DOES_NOT_EXISTS';
103
- }
104
-
105
- } else {
106
- $result['status'] = 'Error';
107
- $result['message'] = 'INVALID_FILE_NAME';
108
- }
109
- return $result;
110
- }
111
-
112
- public function getMalcareWAFContent($confkey) {
113
- return sprintf(
114
- '<?php
115
- // Please validate auto_prepend_file setting before removing this file
116
-
117
- if (file_exists(%1$s)) {
118
- define("MCDATAPATH", %2$s);
119
- define("MCCONFKEY", %3$s);
120
- include_once(%1$s);
121
- }
122
- ?>',
123
- var_export(MCBASEPATH . 'protect/prepend/ignitor.php', true),
124
- var_export($this->mcDataPath(), true),
125
- var_export($confkey, true)
126
- );
127
- }
128
-
129
- public function configureMalcareWAF($confkey) {
130
- $result = array();
131
- if (!$confkey || $confkey === "") {
132
- $result['status'] = 'Error';
133
- $result['message'] = 'INVALID_CONFKEY';
134
- } else {
135
-
136
- $content = $this->getMalcareWAFContent($confkey);
137
- $result = $this->writeToFile($this->mcWAFFilePath(), $content, 0644);
138
- }
139
-
140
- return $result;
141
- }
142
-
143
- public function addPrependToHtaccess($user_ini, $mode) {
144
- $userIniHtaccessContent = '';
145
- if ($user_ini) {
146
- $userIniHtaccessContent = sprintf('<Files "%s">
147
- <IfModule mod_authz_core.c>
148
- Require all denied
149
- </IfModule>
150
- <IfModule !mod_authz_core.c>
151
- Order deny,allow
152
- Deny from all
153
- </IfModule>
154
- </Files>
155
- ', $user_ini);
156
- }
157
-
158
- switch ($mode) {
159
- case BVFWConfig::MODE_APACHEMODPHP:
160
- $htaccessPrependContent = sprintf("# MalCare WAF
161
- <IfModule mod_php5.c>
162
- php_value auto_prepend_file '%s'
163
- </IfModule>
164
- <IfModule mod_php7.c>
165
- php_value auto_prepend_file '%s'
166
- </IfModule>
167
- $userIniHtaccessContent
168
- # END MalCare WAF
169
- ", $this->mcWAFFilePath(), $this->mcWAFFilePath());
170
- break;
171
-
172
- case BVFWConfig::MODE_LITESPEED:
173
- $htaccessPrependContent = sprintf("# MalCare WAF
174
- <IfModule LiteSpeed>
175
- php_value auto_prepend_file '%s'
176
- </IfModule>
177
- <IfModule lsapi_module>
178
- php_value auto_prepend_file '%s'
179
- </IfModule>
180
- $userIniHtaccessContent
181
- # END MalCare WAF
182
- ", $this->mcWAFFilePath(), $this->mcWAFFilePath());
183
- break;
184
-
185
- case BVFWConfig::MODE_APACHESUPHP:
186
- $htaccessPrependContent = sprintf("# MalCare WAF
187
- $userIniHtaccessContent
188
- # END MalCare WAF
189
- ", ABSPATH);
190
- break;
191
-
192
- case BVFWConfig::MODE_CGI_FASTCGI:
193
- if ($userIniHtaccessContent) {
194
- $htaccessPrependContent = sprintf("# MalCare WAF
195
- $userIniHtaccessContent
196
- # END MalCare WAF
197
- ", ABSPATH);
198
- }
199
- break;
200
-
201
- }
202
-
203
- $result = array();
204
- $htaccessPath = $this->htAccessFilePath();
205
-
206
- if (!empty($htaccessPrependContent)) {
207
- $htaccessContent = '';
208
- if (file_exists($htaccessPath)) {
209
- $htaccessContent = file_get_contents($htaccessPath);
210
- }
211
-
212
- if (!empty($htaccessContent)) {
213
- $regex = '/# MalCare WAF.*?# END MalCare WAF/is';
214
- if (preg_match($regex, $htaccessContent, $matches)) {
215
- $htaccessContent = preg_replace($regex, $htaccessPrependContent, $htaccessContent);
216
- } else {
217
- $htaccessContent .= "\n\n" . $htaccessPrependContent;
218
- }
219
- } else {
220
- $htaccessContent = $htaccessPrependContent;
221
- }
222
-
223
- $result = $this->writeToFile($htaccessPath, $htaccessContent, 0755);
224
-
225
- if ($mode == BVFWConfig::MODE_LITESPEED) {
226
- touch($htaccessPath);
227
- }
228
-
229
- }
230
-
231
- if (file_exists($htaccessPath)) {
232
- $result['content'] = file_get_contents($htaccessPath);
233
- }
234
-
235
- return $result;
236
- }
237
-
238
- public function removePrependFromHtaccess() {
239
- $result = array();
240
- $htaccessPath = $this->htAccessFilePath();
241
-
242
- if (file_exists($htaccessPath)) {
243
- $htaccessContent = file_get_contents($htaccessPath);
244
- $regex = '/# MalCare WAF.*?# END MalCare WAF/is';
245
-
246
- if (preg_match($regex, $htaccessContent, $matches)) {
247
- $htaccessContent = preg_replace($regex, '', $htaccessContent);
248
-
249
- $result = $this->writeToFile($htaccessPath, $htaccessContent, 0755);
250
- }
251
- }
252
-
253
- if (file_exists($htaccessPath)) {
254
- $result['content'] = file_get_contents($htaccessPath);
255
- }
256
-
257
- return $result;
258
- }
259
-
260
- public function addPrependToUserini($mode) {
261
- switch ($mode) {
262
- case BVFWConfig::MODE_CGI_FASTCGI:
263
- case BVFWConfig::MODE_NGINX:
264
- case BVFWConfig::MODE_IIS:
265
- case BVFWConfig::MODE_LITESPEED:
266
- case BVFWConfig::MODE_APACHESUPHP:
267
- $useriniPrependContent = sprintf("; MalCare WAF
268
- auto_prepend_file = '%s'
269
- ; END MalCare WAF
270
- ", $this->mcWAFFilePath());
271
- break;
272
- }
273
-
274
- $result = array();
275
- $useriniPath = $this->useriniFilePath();
276
-
277
- if (!empty($useriniPrependContent)) {
278
- $useriniContent = '';
279
- if (file_exists($useriniPath)) {
280
- $useriniContent = file_get_contents($useriniPath);
281
- }
282
- if (!empty($useriniContent)) {
283
- $useriniContent = str_replace('auto_prepend_file', ';auto_prepend_file', $useriniContent);
284
- $regex = '/; MalCare WAF.*?; END MalCare WAF/is';
285
- if (preg_match($regex, $useriniContent, $matches)) {
286
- $useriniContent = preg_replace($regex, $useriniPrependContent, $useriniContent);
287
- } else {
288
- $useriniContent .= "\n\n" . $useriniPrependContent;
289
- }
290
- } else {
291
- $useriniContent = $useriniPrependContent;
292
- }
293
-
294
- $result = $this->writeToFile($useriniPath, $useriniContent, 0755);
295
- }
296
-
297
- if (file_exists($useriniPath)) {
298
- $result['content'] = file_get_contents($useriniPath);
299
- }
300
-
301
- return $result;
302
- }
303
-
304
- public function removePrependFromUserini() {
305
- $result = array();
306
- $useriniPath = $this->UseriniFilePath();
307
-
308
- if (file_exists($useriniPath)) {
309
- $useriniContent = file_get_contents($useriniPath);
310
- $regex = '/; MalCare WAF.*?; END MalCare WAF/is';
311
-
312
- if (preg_match($regex, $useriniContent, $matches)) {
313
- $useriniContent = preg_replace($regex, '', $useriniContent);
314
-
315
- $result = $this->writeToFile($useriniPath, $useriniContent, 0755);
316
- }
317
- }
318
-
319
- if (file_exists($useriniPath)) {
320
- $result['content'] = file_get_contents($useriniPath);
321
- }
322
-
323
- return $result;
324
- }
325
-
326
  public function serverConfig() {
327
  return array(
328
  'software' => $_SERVER['SERVER_SOFTWARE'],
@@ -335,35 +28,6 @@ auto_prepend_file = '%s'
335
  );
336
  }
337
 
338
- public function removeDir($dir) {
339
- $result = array();
340
- if (file_exists($dir)) {
341
- if (rmdir($dir)) {
342
- $result = array('status' => 'Done');
343
- } else {
344
- $result = array('status' => 'Error', 'message' => 'UNABLE_TO_REMOVE_DIR');
345
- }
346
- } else {
347
- $result = array('status' => 'Done', 'message' => 'DIR_DOESNOT_EXISTS');
348
- }
349
-
350
- return $result;
351
- }
352
-
353
- public function removeFile($filename) {
354
- $result = array();
355
- if (file_exists($filename)) {
356
- if (unlink($filename)) {
357
- $result = array('status' => 'Done');
358
- } else {
359
- $result = array('status' => 'Error', 'message' => 'UNABLE_TO_REMOVE_FILE');
360
- }
361
- } else {
362
- $result = array('status' => 'Done', 'message' => 'FILE_DOESNOT_EXISTS');
363
- }
364
- return $result;
365
- }
366
-
367
  public function unBlockLogins() {
368
  $this->settings->deleteTransient('bvlp_block_logins');
369
  $this->settings->setTransient('bvlp_allow_logins', 'true', 1800);
@@ -419,66 +83,6 @@ auto_prepend_file = '%s'
419
  case "svrcnf":
420
  $resp = array("serverconfig" => $this->serverConfig());
421
  break;
422
- case "gtmcwafcntent":
423
- $resp = array('content' => $this->getMalcareWAFContent($params['confkey']));
424
- break;
425
- case "wrtmcdtafle":
426
- $permissions = array_key_exists('permissions', $params) ? $params['permissions'] : 0664;
427
- $confkey = $params['confkey'];
428
- $fname = $params['fname'];
429
- $content = $params['content'];
430
- $resp = array('writetomcdatafile' => $this->writeToMcDataFile($fname, $content, $confkey, $permissions));
431
- break;
432
- case "cnfgrewaf":
433
- $confkey = $params['confkey'];
434
- $resp = array('configurewaf' => $this->configureMalcareWAF($confkey));
435
- break;
436
- case "rmmcdta":
437
- $name = $params['name'];
438
- if (in_array($name, BVFWConfig::$validDeletableFiles)) {
439
- switch($name) {
440
- case "mc.conf":
441
- $name = $this->mcConfigFilePath($params['confkey']);
442
- $resp = $this->removeFile($name);
443
- break;
444
- case "mc_ips.conf":
445
- $name = $this->mcIPsFilePath($params['confkey']);
446
- $resp = $this->removeFile($name);
447
- break;
448
- case "malcare-waf.php":
449
- $name = $this->mcWAFFilePath();
450
- $resp = $this->removeFile($name);
451
- break;
452
- case "mc.log":
453
- $name = $this->mcLogFilePath($params['confkey']);
454
- $resp = $this->removeFile($name);
455
- break;
456
- case "mc_data":
457
- $dir = $this->mcDataPath();
458
- $resp = $this->removeDir($dir);
459
- break;
460
- default:
461
- $resp = array('status' => 'Error', 'message' => 'INCORRECT_FILENAME');
462
- }
463
- } else {
464
- $resp = array('status' => 'Error', 'message' => 'INCORRECT_FILENAME');
465
- }
466
- break;
467
- case "addprepndtohtacess":
468
- $user_ini = $params['user_ini'];
469
- $mode = intval($params['mode']);
470
- $resp = array('prependtohtaccess' => $this->addPrependToHtaccess($user_ini, $mode));
471
- break;
472
- case "rmprepndfrmhtacess":
473
- $resp = array('removefromhtaccess' => $this->removePrependFromHtaccess());
474
- break;
475
- case "addprepndtousrini":
476
- $mode = intval($params['mode']);
477
- $resp = array('prependtouserini' => $this->addPrependToUserini($mode));
478
- break;
479
- case "rmprepndfrmusrini":
480
- $resp = array('removefromuserini' => $this->removePrependFromUserini());
481
- break;
482
  case "setptplug":
483
  $this->settings->updateOption('bvptplug', $params['ptplug']);
484
  $resp = array("setptplug" => $this->settings->getOption('bvptplug'));
@@ -508,4 +112,4 @@ auto_prepend_file = '%s'
508
  return $resp;
509
  }
510
  }
511
- endif;
16
  $this->settings = $callback_handler->settings;
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  public function serverConfig() {
20
  return array(
21
  'software' => $_SERVER['SERVER_SOFTWARE'],
28
  );
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  public function unBlockLogins() {
32
  $this->settings->deleteTransient('bvlp_block_logins');
33
  $this->settings->setTransient('bvlp_allow_logins', 'true', 1800);
83
  case "svrcnf":
84
  $resp = array("serverconfig" => $this->serverConfig());
85
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  case "setptplug":
87
  $this->settings->updateOption('bvptplug', $params['ptplug']);
88
  $resp = array("setptplug" => $this->settings->getOption('bvptplug'));
112
  return $resp;
113
  }
114
  }
115
+ endif;
info.php CHANGED
@@ -9,7 +9,7 @@ if (!class_exists('MCInfo')) :
9
  public $badgeinfo = 'mcbadge';
10
  public $ip_header_option = 'mcipheader';
11
  public $brand_option = 'mcbrand';
12
- public $version = '3.8';
13
  public $webpage = 'https://www.malcare.com';
14
  public $appurl = 'https://app.malcare.com';
15
  public $slug = 'malcare-security/malcare.php';
9
  public $badgeinfo = 'mcbadge';
10
  public $ip_header_option = 'mcipheader';
11
  public $brand_option = 'mcbrand';
12
+ public $version = '4.2';
13
  public $webpage = 'https://www.malcare.com';
14
  public $appurl = 'https://app.malcare.com';
15
  public $slug = 'malcare-security/malcare.php';
malcare.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: https://www.malcare.com
5
  Description: WordPress Security, Firewall and Malware Scanner
6
  Author: MalCare Security
7
  Author URI: https://www.malcare.com
8
- Version: 3.8
9
  Network: True
10
  */
11
 
@@ -87,7 +87,7 @@ if ((array_key_exists('bvplugname', $_REQUEST)) && ($_REQUEST['bvplugname'] == "
87
  require_once dirname( __FILE__ ) . '/callback/request.php';
88
  require_once dirname( __FILE__ ) . '/recover.php';
89
 
90
- $pubkey = $_REQUEST['pubkey'];
91
 
92
  if (array_key_exists('rcvracc', $_REQUEST)) {
93
  $account = MCRecover::find($bvsettings, $pubkey);
5
  Description: WordPress Security, Firewall and Malware Scanner
6
  Author: MalCare Security
7
  Author URI: https://www.malcare.com
8
+ Version: 4.2
9
  Network: True
10
  */
11
 
87
  require_once dirname( __FILE__ ) . '/callback/request.php';
88
  require_once dirname( __FILE__ ) . '/recover.php';
89
 
90
+ $pubkey = MCAccount::sanitizeKey($_REQUEST['pubkey']);
91
 
92
  if (array_key_exists('rcvracc', $_REQUEST)) {
93
  $account = MCRecover::find($bvsettings, $pubkey);
readme.txt CHANGED
@@ -6,7 +6,7 @@ Donate link: https://www.malcare.com
6
  Requires at least: 4.0
7
  Tested up to: 5.4
8
  Requires PHP: 5.4.0
9
- Stable tag: 3.8
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
 
@@ -218,6 +218,11 @@ FTP details input into MalCare is processed on our servers. We need your FTP cre
218
  8. With BlogVault's White-Label Solution you can showcase our service under your own brilliant brand.
219
 
220
  == CHANGELOG ==
 
 
 
 
 
221
  = 3.8 =
222
  * Updated MalCare landing page front-end
223
 
6
  Requires at least: 4.0
7
  Tested up to: 5.4
8
  Requires PHP: 5.4.0
9
+ Stable tag: 4.2
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
 
218
  8. With BlogVault's White-Label Solution you can showcase our service under your own brilliant brand.
219
 
220
  == CHANGELOG ==
221
+ = 4.2 =
222
+ * Robust write callbacks
223
+ * Improved and Robust prepend in Firewall Support
224
+ * Without FTP cleanup and restore support
225
+
226
  = 3.8 =
227
  * Updated MalCare landing page front-end
228