PluginProbe
The WP Remote WordPress Plugin / 6.36
The WP Remote WordPress Plugin v6.36
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 +137 -44 5.096.36 View file →
@@ -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]);
@@ -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) {
@@ -215,7 +211,104 @@
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;