PluginProbe
The WP Remote WordPress Plugin / 6.44
The WP Remote WordPress Plugin v6.44
6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 5.73 All 53 releases
← All changes | callback/request.php +141 -48 5.096.44 View file →
@@ -1,9 +1,9 @@
1 1 <?php
2 2
3 3 if (!defined('ABSPATH')) exit;
4 -if (!class_exists('BVCallbackRequest')) :
5 - class BVCallbackRequest {
4 +if (!class_exists('WPRCallbackRequest')) :
5 + class WPRCallbackRequest {
6 6 public $params;
7 7 public $method;
8 8 public $wing;
9 9 public $is_afterload;
@@ -9,10 +9,11 @@
9 9 public $is_afterload;
10 10 public $is_admin_ajax;
11 11 public $is_debug;
12 12 public $account;
13 - public $calculated_mac;
13 + public $settings;
14 14 public $sig;
15 + public $sighshalgo;
15 16 public $time;
16 17 public $version;
17 18 public $is_sha1;
18 19 public $bvb64stream;
@@ -17,12 +18,22 @@
17 18 public $is_sha1;
18 19 public $bvb64stream;
19 20 public $bvb64cksize;
20 21 public $checksum;
22 + public $error = array();
23 + public $pubkey_name;
24 + public $bvprmsmac;
25 + public $bvboundry;
21 26
22 - public function __construct($account, $in_params) {
27 + private static $SIG_HASH_ALGO_MAP = array(
28 + '1' => OPENSSL_ALGO_SHA1,
29 + '7' => OPENSSL_ALGO_SHA256
30 + );
31 +
32 + public function __construct($account, $in_params, $settings) {
23 33 $this->params = array();
24 34 $this->account = $account;
35 + $this->settings = $settings;
25 36 $this->wing = $in_params['wing'];
26 37 $this->method = $in_params['bvMethod'];
27 38 $this->is_afterload = array_key_exists('afterload', $in_params);
28 39 $this->is_admin_ajax = array_key_exists('adajx', $in_params);
@@ -27,8 +38,9 @@
27 38 $this->is_afterload = array_key_exists('afterload', $in_params);
28 39 $this->is_admin_ajax = array_key_exists('adajx', $in_params);
29 40 $this->is_debug = array_key_exists('bvdbg', $in_params);
30 41 $this->sig = $in_params['sig'];
42 + $this->sighshalgo = !empty($in_params['sighshalgo']) ? $in_params['sighshalgo'] : '1';
31 43 $this->time = intval($in_params['bvTime']);
32 44 $this->version = $in_params['bvVersion'];
33 45 $this->is_sha1 = array_key_exists('sha1', $in_params);
34 46 $this->bvb64stream = isset($in_params['bvb64stream']);
@@ -33,8 +45,12 @@
33 45 $this->is_sha1 = array_key_exists('sha1', $in_params);
34 46 $this->bvb64stream = isset($in_params['bvb64stream']);
35 47 $this->bvb64cksize = array_key_exists('bvb64cksize', $in_params) ? intval($in_params['bvb64cksize']) : false;
36 48 $this->checksum = array_key_exists('checksum', $in_params) ? $in_params['checksum'] : false;
49 + $this->pubkey_name = !empty($in_params['pubkeyname']) ?
50 + WPRAccount::sanitizeKey($in_params['pubkeyname']) : 'm_public';
51 + $this->bvprmsmac = !empty($in_params['bvprmsmac']) ? WPRAccount::sanitizeKey($in_params['bvprmsmac']) : "";
52 + $this->bvboundry = !empty($in_params['bvboundry']) ? $in_params['bvboundry'] : "";
37 53 }
38 54
39 55 public function isAPICall() {
40 56 return array_key_exists('apicall', $this->params);
@@ -39,38 +55,25 @@
39 55 public function isAPICall() {
40 56 return array_key_exists('apicall', $this->params);
41 57 }
42 58
43 - public function curlRequest($url, $body) {
44 - $ch = curl_init($url);
45 - curl_setopt($ch, CURLOPT_POST, 1);
46 - curl_setopt($ch, CURLOPT_TIMEOUT, 15);
47 - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($body));
48 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
49 - return curl_exec($ch);
50 - }
59 + public function http_request($url, $body) {
60 + $body = http_build_query($body);
61 + $response = wp_remote_post($url, array(
62 + 'body' => $body,
63 + 'timeout' => 15,
64 + 'headers' => array(
65 + 'Content-Type' => 'application/x-www-form-urlencoded',
66 + ),
67 + ));
51 68
52 - public function fileGetContentRequest($url, $body) {
53 - $options = array(
54 - 'http' => array(
55 - 'header' => "Content-type: application/x-www-form-urlencoded\r\n",
56 - 'method' => 'POST',
57 - 'content' => http_build_query($body)
58 - )
59 - );
69 + if (is_wp_error($response)) {
70 + return false;
71 + }
60 72
61 - $context = stream_context_create($options);
62 - return file_get_contents($url, false, $context);
73 + return wp_remote_retrieve_body($response);
63 74 }
64 75
65 - public function http_request($url, $body) {
66 - if (in_array('curl', get_loaded_extensions())) {
67 - return $this->curlRequest($url, $body);
68 - } else {
69 - return $this->fileGetContentRequest($url, $body);
70 - }
71 - }
72 -
73 76 public function get_params_via_api($params_key, $apiurl) {
74 77 $res = $this->http_request($apiurl, array('bvkey' => $params_key));
75 78
76 79 if ($res === FALSE) {
@@ -83,9 +86,10 @@
83 86 public function info() {
84 87 $info = array(
85 88 "requestedsig" => $this->sig,
86 89 "requestedtime" => $this->time,
87 - "requestedversion" => $this->version
90 + "requestedversion" => $this->version,
91 + "error" => $this->error
88 92 );
89 93 if ($this->is_debug) {
90 94 $info["inreq"] = $this->params;
91 95 }
@@ -94,11 +98,8 @@
94 98 }
95 99 if ($this->is_afterload) {
96 100 $info["afterload"] = true;
97 101 }
98 - if ($this->calculated_mac) {
99 - $info["calculated_mac"] = $this->calculated_mac;
100 - }
101 102 return $info;
102 103 }
103 104
104 105 public function processParams($in_params) {
@@ -127,22 +128,17 @@
127 128 $in_params["bvprms"] = $pdata;
128 129 }
129 130 }
130 131
131 - if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms']) &&
132 - array_key_exists('bvprmsmac', $in_params) && isset($in_params['bvprmsmac'])) {
133 - $digest_algo = 'SHA1';
134 - $sent_mac = WPRAccount::sanitizeKey($in_params['bvprmsmac']);
135 -
136 - if (array_key_exists('bvprmshshalgo', $in_params) && isset($in_params['bvprmshshalgo'])) {
137 - $digest_algo = $in_params['bvprmshshalgo'];
132 + if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
133 + if (!empty($in_params['bvprmshshalgo']) && $in_params['bvprmshshalgo'] === 'sha256') {
134 + $calculated_mac = hash_hmac('SHA256', $in_params['bvprms'], $this->account->secret);
135 + } else {
136 + $calculated_mac = hash_hmac('SHA1', $in_params['bvprms'], $this->account->secret);
138 137 }
139 138
140 - $calculated_mac = hash_hmac($digest_algo, $in_params['bvprms'], $this->account->secret);
141 - $this->calculated_mac = substr($calculated_mac, 0, 6);
139 + if ($this->compare_mac($this->bvprmsmac, $calculated_mac) === true) {
142 140
143 - if ($this->compare_mac($sent_mac, $calculated_mac) === true) {
144 -
145 141 if (array_key_exists('b64', $in_params)) {
146 142 foreach ($in_params['b64'] as $key) {
147 143 if (is_array($in_params[$key])) {
148 144 $in_params[$key] = array_map('base64_decode', $in_params[$key]);
@@ -159,9 +155,9 @@
159 155 }
160 156
161 157 if (array_key_exists('sersafe', $in_params)) {
162 158 $key = $in_params['sersafe'];
163 - $in_params[$key] = BVCallbackRequest::serialization_safe_decode($in_params[$key]);
159 + $in_params[$key] = WPRCallbackRequest::serialization_safe_decode($in_params[$key]);
164 160 }
165 161
166 162 if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
167 163 $params = $in_params['bvprms'];
@@ -181,8 +177,9 @@
181 177 }
182 178
183 179 if (array_key_exists('memset', $in_params)) {
184 180 $val = intval($in_params['memset']);
181 + // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for memory limit adjustment
185 182 @ini_set('memory_limit', $val.'M');
186 183 }
187 184
188 185 return $params;
@@ -187,9 +184,8 @@
187 184
188 185 return $params;
189 186 }
190 187 }
191 -
192 188 return false;
193 189 }
194 190
195 191 private function compare_mac($l_hash, $r_hash) {
@@ -209,13 +205,110 @@
209 205 }
210 206
211 207 public static function serialization_safe_decode($data) {
212 208 if (is_array($data)) {
213 - $data = array_map(array('BVCallbackRequest', 'serialization_safe_decode'), $data);
209 + $data = array_map(array('WPRCallbackRequest', 'serialization_safe_decode'), $data);
214 210 } elseif (is_string($data)) {
215 211 $data = base64_decode($data);
216 212 }
217 213
218 214 return $data;
215 + }
216 +
217 + public function authenticate() {
218 + if (!$this->account) {
219 + $this->error["message"] = "ACCOUNT_NOT_FOUND";
220 + return false;
221 + }
222 +
223 + $bv_last_recv_time = $this->settings->getOption('bvLastRecvTime');
224 + if ($this->time < intval($bv_last_recv_time) - 300) {
225 + return false;
226 + }
227 +
228 + $data = $this->method.$this->account->secret.$this->time.$this->version.$this->bvprmsmac;
229 + if (!$this->verify($data, base64_decode($this->sig), $this->sighshalgo)) {
230 + return false;
231 + }
232 + $this->settings->updateOption('bvLastRecvTime', $this->time);
233 +
234 + return 1;
235 + }
236 +
237 + public function verify($data, $sig, $sighshalgo) {
238 + if (!function_exists('openssl_verify') || !function_exists('openssl_pkey_get_public')) {
239 + $this->error["message"] = "OPENSSL_FUNCS_NOT_FOUND";
240 + return false;
241 + }
242 +
243 + $openssl_algo = array_key_exists($sighshalgo, self::$SIG_HASH_ALGO_MAP) ? self::$SIG_HASH_ALGO_MAP[$sighshalgo] : null;
244 + if ($openssl_algo === null) {
245 + $this->error["message"] = "UNSUPPORTED_HASH_ALGORITHM: " . $sighshalgo;
246 + return false;
247 + }
248 +
249 + $key_file = dirname( __DIR__ ) . '/public_keys/' . $this->pubkey_name . '.pub';
250 + if (!file_exists($key_file)) {
251 + $this->error["message"] = "PUBLIC_KEY_NOT_FOUND";
252 + return false;
253 + }
254 +
255 + $public_key_str = WPRWPFileSystem::getInstance()->getContents($key_file);
256 +
257 + $public_key = openssl_pkey_get_public($public_key_str);
258 + if (!$public_key) {
259 + $this->error["message"] = "UNABLE_TO_LOAD_PUBLIC_KEY";
260 + return false;
261 + }
262 +
263 + $verify = openssl_verify($data, $sig, $public_key, $openssl_algo);
264 + if ($verify === 1) {
265 + return true;
266 + } elseif ($verify === 0) {
267 + $this->error["message"] = "INCORRECT_SIGNATURE";
268 + $this->error["pubkey_sig"] = substr(hash('md5', $public_key_str), 0, 8);
269 + } else {
270 + $this->error["message"] = "OPENSSL_VERIFY_FAILED";
271 + }
272 + return false;
273 + }
274 +
275 + public function corruptedParamsResp() {
276 + $bvinfo = new WPRInfo($this->settings);
277 +
278 + return array(
279 + "account_info" => $this->account->info(),
280 + "request_info" => $this->info(),
281 + "bvinfo" => $bvinfo->info(),
282 + "statusmsg" => "BVPRMS_CORRUPTED"
283 + );
284 + }
285 +
286 + public function authFailedResp() {
287 + $api_public_key = WPRAccount::getApiPublicKey($this->settings);
288 + $default_secret = WPRRecover::getDefaultSecret($this->settings);
289 + $default_account_pubkey = WPRAccount::getDefaultPublicKey();
290 + $bvinfo = new WPRInfo($this->settings);
291 + $resp = array(
292 + "request_info" => $this->info(),
293 + "bvinfo" => $bvinfo->info(),
294 + "statusmsg" => "FAILED_AUTH",
295 + "api_pubkey" => substr($api_public_key, 0, 8),
296 + "def_key_status" => WPRRecover::getSecretStatus($this->settings),
297 + "def_sigmatch" => substr(hash('sha1', $this->method.$default_secret.$this->time.$this->version), 0, 8)
298 + );
299 +
300 + if (is_string($default_account_pubkey) && strlen($default_account_pubkey) >= 32) {
301 + $resp["default_account_pubkey"] = substr($default_account_pubkey, 0, 8);
302 + }
303 +
304 + if ($this->account) {
305 + $resp["account_info"] = $this->account->info();
306 + $resp["sigmatch"] = substr(hash('sha1', $this->method.$this->account->secret.$this->time.$this->version), 0, 6);
307 + } else {
308 + $resp["account_info"] = array("error" => "ACCOUNT_NOT_FOUND");
309 + }
310 +
311 + return $resp;
219 312 }
220 313 }
221 314 endif;