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 +80 -43 5.166.36 View file →
@@ -11,8 +11,9 @@
11 11 public $is_debug;
12 12 public $account;
13 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;
@@ -18,9 +19,17 @@
18 19 public $bvb64stream;
19 20 public $bvb64cksize;
20 21 public $checksum;
21 22 public $error = array();
23 + public $pubkey_name;
24 + public $bvprmsmac;
25 + public $bvboundry;
22 26
27 + private static $SIG_HASH_ALGO_MAP = array(
28 + '1' => OPENSSL_ALGO_SHA1,
29 + '7' => OPENSSL_ALGO_SHA256
30 + );
31 +
23 32 public function __construct($account, $in_params, $settings) {
24 33 $this->params = array();
25 34 $this->account = $account;
26 35 $this->settings = $settings;
@@ -29,8 +38,9 @@
29 38 $this->is_afterload = array_key_exists('afterload', $in_params);
30 39 $this->is_admin_ajax = array_key_exists('adajx', $in_params);
31 40 $this->is_debug = array_key_exists('bvdbg', $in_params);
32 41 $this->sig = $in_params['sig'];
42 + $this->sighshalgo = !empty($in_params['sighshalgo']) ? $in_params['sighshalgo'] : '1';
33 43 $this->time = intval($in_params['bvTime']);
34 44 $this->version = $in_params['bvVersion'];
35 45 $this->is_sha1 = array_key_exists('sha1', $in_params);
36 46 $this->bvb64stream = isset($in_params['bvb64stream']);
@@ -35,8 +45,12 @@
35 45 $this->is_sha1 = array_key_exists('sha1', $in_params);
36 46 $this->bvb64stream = isset($in_params['bvb64stream']);
37 47 $this->bvb64cksize = array_key_exists('bvb64cksize', $in_params) ? intval($in_params['bvb64cksize']) : false;
38 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'] : "";
39 53 }
40 54
41 55 public function isAPICall() {
42 56 return array_key_exists('apicall', $this->params);
@@ -41,38 +55,25 @@
41 55 public function isAPICall() {
42 56 return array_key_exists('apicall', $this->params);
43 57 }
44 58
45 - public function curlRequest($url, $body) {
46 - $ch = curl_init($url);
47 - curl_setopt($ch, CURLOPT_POST, 1);
48 - curl_setopt($ch, CURLOPT_TIMEOUT, 15);
49 - curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($body));
50 - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
51 - return curl_exec($ch);
52 - }
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 + ));
53 68
54 - public function fileGetContentRequest($url, $body) {
55 - $options = array(
56 - 'http' => array(
57 - 'header' => "Content-type: application/x-www-form-urlencoded\r\n",
58 - 'method' => 'POST',
59 - 'content' => http_build_query($body)
60 - )
61 - );
69 + if (is_wp_error($response)) {
70 + return false;
71 + }
62 72
63 - $context = stream_context_create($options);
64 - return file_get_contents($url, false, $context);
73 + return wp_remote_retrieve_body($response);
65 74 }
66 75
67 - public function http_request($url, $body) {
68 - if (in_array('curl', get_loaded_extensions())) {
69 - return $this->curlRequest($url, $body);
70 - } else {
71 - return $this->fileGetContentRequest($url, $body);
72 - }
73 - }
74 -
75 76 public function get_params_via_api($params_key, $apiurl) {
76 77 $res = $this->http_request($apiurl, array('bvkey' => $params_key));
77 78
78 79 if ($res === FALSE) {
@@ -127,12 +128,16 @@
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'])) {
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);
137 + }
133 138
134 - if ($this->verify($in_params['bvprms'], base64_decode($in_params['bvprmsmac'])) === true) {
139 + if ($this->compare_mac($this->bvprmsmac, $calculated_mac) === true) {
135 140
136 141 if (array_key_exists('b64', $in_params)) {
137 142 foreach ($in_params['b64'] as $key) {
138 143 if (is_array($in_params[$key])) {
@@ -172,8 +177,9 @@
172 177 }
173 178
174 179 if (array_key_exists('memset', $in_params)) {
175 180 $val = intval($in_params['memset']);
181 + // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for memory limit adjustment
176 182 @ini_set('memory_limit', $val.'M');
177 183 }
178 184
179 185 return $params;
@@ -178,10 +184,25 @@
178 184
179 185 return $params;
180 186 }
181 187 }
188 + return false;
189 + }
182 190
183 - return false;
191 + private function compare_mac($l_hash, $r_hash) {
192 + if (!is_string($l_hash) || !is_string($r_hash)) {
193 + return false;
194 + }
195 +
196 + if (strlen($l_hash) !== strlen($r_hash)) {
197 + return false;
198 + }
199 +
200 + if (function_exists('hash_equals')) {
201 + return hash_equals($l_hash, $r_hash);
202 + } else {
203 + return $l_hash === $r_hash;
204 + }
184 205 }
185 206
186 207 public static function serialization_safe_decode($data) {
187 208 if (is_array($data)) {
@@ -194,9 +215,9 @@
194 215 }
195 216
196 217 public function authenticate() {
197 218 if (!$this->account) {
198 - array_push($this->error, "ACCOUNT_NOT_FOUND");
219 + $this->error["message"] = "ACCOUNT_NOT_FOUND";
199 220 return false;
200 221 }
201 222
202 223 $bv_last_recv_time = $this->settings->getOption('bvLastRecvTime');
@@ -203,10 +224,10 @@
203 224 if ($this->time < intval($bv_last_recv_time) - 300) {
204 225 return false;
205 226 }
206 227
207 - $data = $this->method.$this->account->secret.$this->time.$this->version;
208 - if (!$this->verify($data, base64_decode($this->sig))) {
228 + $data = $this->method.$this->account->secret.$this->time.$this->version.$this->bvprmsmac;
229 + if (!$this->verify($data, base64_decode($this->sig), $this->sighshalgo)) {
209 230 return false;
210 231 }
211 232 $this->settings->updateOption('bvLastRecvTime', $this->time);
212 233
@@ -212,32 +233,42 @@
212 233
213 234 return 1;
214 235 }
215 236
216 - public function verify($data, $sig) {
217 - if (!function_exists('openssl_verify')) {
218 - array_push($this->error, "OPENSSL_VERIFY_FUNC_NOT_FOUND");
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";
219 240 return false;
220 241 }
221 242
222 - $key_file = dirname( __FILE__ ) . '/../public_keys/m_public.pub';
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';
223 250 if (!file_exists($key_file)) {
224 - array_push($this->error, "PUBLIC_KEY_NOT_FOUND");
251 + $this->error["message"] = "PUBLIC_KEY_NOT_FOUND";
225 252 return false;
226 253 }
227 - $public_key = file_get_contents($key_file);
254 +
255 + $public_key_str = WPRWPFileSystem::getInstance()->getContents($key_file);
256 +
257 + $public_key = openssl_pkey_get_public($public_key_str);
228 258 if (!$public_key) {
229 - array_push($this->error, "UNABLE_TO_LOAD_PUBLIC_KEY");
259 + $this->error["message"] = "UNABLE_TO_LOAD_PUBLIC_KEY";
230 260 return false;
231 261 }
232 262
233 - $verify = openssl_verify($data, $sig, $public_key);
263 + $verify = openssl_verify($data, $sig, $public_key, $openssl_algo);
234 264 if ($verify === 1) {
235 265 return true;
236 266 } elseif ($verify === 0) {
237 - array_push($this->error, "INCORRECT_SIGNATURE");
267 + $this->error["message"] = "INCORRECT_SIGNATURE";
268 + $this->error["pubkey_sig"] = substr(hash('md5', $public_key_str), 0, 8);
238 269 } else {
239 - array_push($this->error, "OPENSSL_VERIFY_FAILED");
270 + $this->error["message"] = "OPENSSL_VERIFY_FAILED";
240 271 }
241 272 return false;
242 273 }
243 274
@@ -254,8 +285,9 @@
254 285
255 286 public function authFailedResp() {
256 287 $api_public_key = WPRAccount::getApiPublicKey($this->settings);
257 288 $default_secret = WPRRecover::getDefaultSecret($this->settings);
289 + $default_account_pubkey = WPRAccount::getDefaultPublicKey();
258 290 $bvinfo = new WPRInfo($this->settings);
259 291 $resp = array(
260 292 "request_info" => $this->info(),
261 293 "bvinfo" => $bvinfo->info(),
@@ -260,10 +292,15 @@
260 292 "request_info" => $this->info(),
261 293 "bvinfo" => $bvinfo->info(),
262 294 "statusmsg" => "FAILED_AUTH",
263 295 "api_pubkey" => substr($api_public_key, 0, 8),
296 + "def_key_status" => WPRRecover::getSecretStatus($this->settings),
264 297 "def_sigmatch" => substr(hash('sha1', $this->method.$default_secret.$this->time.$this->version), 0, 8)
265 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 + }
266 303
267 304 if ($this->account) {
268 305 $resp["account_info"] = $this->account->info();
269 306 $resp["sigmatch"] = substr(hash('sha1', $this->method.$this->account->secret.$this->time.$this->version), 0, 6);