PluginProbe
The WP Remote WordPress Plugin / trunk
The WP Remote WordPress Plugin vtrunk
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 +149 -49 5.05trunk View file →
@@ -1,18 +1,21 @@
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;
10 + public $is_aftershutdown;
11 + public $keep_page_output;
10 12 public $is_admin_ajax;
11 13 public $is_debug;
12 14 public $account;
13 - public $calculated_mac;
15 + public $settings;
14 16 public $sig;
17 + public $sighshalgo;
15 18 public $time;
16 19 public $version;
17 20 public $is_sha1;
18 21 public $bvb64stream;
@@ -17,24 +20,42 @@
17 20 public $is_sha1;
18 21 public $bvb64stream;
19 22 public $bvb64cksize;
20 23 public $checksum;
24 + public $error = array();
25 + public $pubkey_name;
26 + public $bvprmsmac;
27 + public $bvboundry;
21 28
22 - public function __construct($account, $in_params) {
29 + private static $SIG_HASH_ALGO_MAP = array(
30 + '1' => OPENSSL_ALGO_SHA1,
31 + '7' => OPENSSL_ALGO_SHA256
32 + );
33 +
34 + public function __construct($account, $in_params, $settings) {
23 35 $this->params = array();
24 36 $this->account = $account;
37 + $this->settings = $settings;
25 38 $this->wing = $in_params['wing'];
26 39 $this->method = $in_params['bvMethod'];
27 40 $this->is_afterload = array_key_exists('afterload', $in_params);
41 + $this->is_aftershutdown = array_key_exists('aftershutdown', $in_params);
42 + $this->keep_page_output = $this->is_aftershutdown &&
43 + array_key_exists('keeppageoutput', $in_params);
28 44 $this->is_admin_ajax = array_key_exists('adajx', $in_params);
29 45 $this->is_debug = array_key_exists('bvdbg', $in_params);
30 46 $this->sig = $in_params['sig'];
47 + $this->sighshalgo = !empty($in_params['sighshalgo']) ? $in_params['sighshalgo'] : '1';
31 48 $this->time = intval($in_params['bvTime']);
32 49 $this->version = $in_params['bvVersion'];
33 50 $this->is_sha1 = array_key_exists('sha1', $in_params);
34 51 $this->bvb64stream = isset($in_params['bvb64stream']);
35 - $this->bvb64cksize = array_key_exists('bvb64cksize', $in_params) ? intval($in_params['bvb64cksize']) : false;
52 + $this->bvb64cksize = array_key_exists('bvb64cksize', $in_params) ? intval($in_params['bvb64cksize']) : 0;
36 53 $this->checksum = array_key_exists('checksum', $in_params) ? $in_params['checksum'] : false;
54 + $this->pubkey_name = !empty($in_params['pubkeyname']) ?
55 + WPRAccount::sanitizeKey($in_params['pubkeyname']) : 'm_public';
56 + $this->bvprmsmac = !empty($in_params['bvprmsmac']) ? WPRAccount::sanitizeKey($in_params['bvprmsmac']) : "";
57 + $this->bvboundry = !empty($in_params['bvboundry']) ? $in_params['bvboundry'] : "";
37 58 }
38 59
39 60 public function isAPICall() {
40 61 return array_key_exists('apicall', $this->params);
@@ -39,38 +60,25 @@
39 60 public function isAPICall() {
40 61 return array_key_exists('apicall', $this->params);
41 62 }
42 63
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 - }
64 + public function http_request($url, $body) {
65 + $body = http_build_query($body);
66 + $response = wp_remote_post($url, array(
67 + 'body' => $body,
68 + 'timeout' => 15,
69 + 'headers' => array(
70 + 'Content-Type' => 'application/x-www-form-urlencoded',
71 + ),
72 + ));
51 73
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 - );
74 + if (is_wp_error($response)) {
75 + return false;
76 + }
60 77
61 - $context = stream_context_create($options);
62 - return file_get_contents($url, false, $context);
78 + return wp_remote_retrieve_body($response);
63 79 }
64 80
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 81 public function get_params_via_api($params_key, $apiurl) {
74 82 $res = $this->http_request($apiurl, array('bvkey' => $params_key));
75 83
76 84 if ($res === FALSE) {
@@ -83,9 +91,10 @@
83 91 public function info() {
84 92 $info = array(
85 93 "requestedsig" => $this->sig,
86 94 "requestedtime" => $this->time,
87 - "requestedversion" => $this->version
95 + "requestedversion" => $this->version,
96 + "error" => $this->error
88 97 );
89 98 if ($this->is_debug) {
90 99 $info["inreq"] = $this->params;
91 100 }
@@ -94,11 +103,14 @@
94 103 }
95 104 if ($this->is_afterload) {
96 105 $info["afterload"] = true;
97 106 }
98 - if ($this->calculated_mac) {
99 - $info["calculated_mac"] = $this->calculated_mac;
107 + if ($this->is_aftershutdown) {
108 + $info["aftershutdown"] = true;
100 109 }
110 + if ($this->keep_page_output) {
111 + $info["keeppageoutput"] = true;
112 + }
101 113 return $info;
102 114 }
103 115
104 116 public function processParams($in_params) {
@@ -127,22 +139,17 @@
127 139 $in_params["bvprms"] = $pdata;
128 140 }
129 141 }
130 142
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'];
143 + if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
144 + if (!empty($in_params['bvprmshshalgo']) && $in_params['bvprmshshalgo'] === 'sha256') {
145 + $calculated_mac = hash_hmac('SHA256', $in_params['bvprms'], $this->account->secret);
146 + } else {
147 + $calculated_mac = hash_hmac('SHA1', $in_params['bvprms'], $this->account->secret);
138 148 }
139 149
140 - $calculated_mac = hash_hmac($digest_algo, $in_params['bvprms'], $this->account->secret);
141 - $this->calculated_mac = substr($calculated_mac, 0, 6);
150 + if ($this->compare_mac($this->bvprmsmac, $calculated_mac) === true) {
142 151
143 - if ($this->compare_mac($sent_mac, $calculated_mac) === true) {
144 -
145 152 if (array_key_exists('b64', $in_params)) {
146 153 foreach ($in_params['b64'] as $key) {
147 154 if (is_array($in_params[$key])) {
148 155 $in_params[$key] = array_map('base64_decode', $in_params[$key]);
@@ -159,9 +166,9 @@
159 166 }
160 167
161 168 if (array_key_exists('sersafe', $in_params)) {
162 169 $key = $in_params['sersafe'];
163 - $in_params[$key] = BVCallbackRequest::serialization_safe_decode($in_params[$key]);
170 + $in_params[$key] = WPRCallbackRequest::serialization_safe_decode($in_params[$key]);
164 171 }
165 172
166 173 if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
167 174 $params = $in_params['bvprms'];
@@ -181,8 +188,9 @@
181 188 }
182 189
183 190 if (array_key_exists('memset', $in_params)) {
184 191 $val = intval($in_params['memset']);
192 + // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for memory limit adjustment
185 193 @ini_set('memory_limit', $val.'M');
186 194 }
187 195
188 196 return $params;
@@ -187,9 +195,8 @@
187 195
188 196 return $params;
189 197 }
190 198 }
191 -
192 199 return false;
193 200 }
194 201
195 202 private function compare_mac($l_hash, $r_hash) {
@@ -209,9 +216,9 @@
209 216 }
210 217
211 218 public static function serialization_safe_decode($data) {
212 219 if (is_array($data)) {
213 - $data = array_map(array('BVCallbackRequest', 'serialization_safe_decode'), $data);
220 + $data = array_map(array('WPRCallbackRequest', 'serialization_safe_decode'), $data);
214 221 } elseif (is_string($data)) {
215 222 $data = base64_decode($data);
216 223 }
217 224
@@ -216,6 +223,99 @@
216 223 }
217 224
218 225 return $data;
219 226 }
227 +
228 + public function authenticate() {
229 + if (!$this->account) {
230 + $this->error["message"] = "ACCOUNT_NOT_FOUND";
231 + return false;
232 + }
233 +
234 + $bv_last_recv_time = $this->settings->getOption('bvLastRecvTime');
235 + if ($this->time < intval($bv_last_recv_time) - 300) {
236 + return false;
237 + }
238 +
239 + $data = $this->method.$this->account->secret.$this->time.$this->version.$this->bvprmsmac;
240 + if (!$this->verify($data, base64_decode($this->sig), $this->sighshalgo)) {
241 + return false;
242 + }
243 + $this->settings->updateOption('bvLastRecvTime', $this->time);
244 +
245 + return 1;
246 + }
247 +
248 + public function verify($data, $sig, $sighshalgo) {
249 + if (!function_exists('openssl_verify') || !function_exists('openssl_pkey_get_public')) {
250 + $this->error["message"] = "OPENSSL_FUNCS_NOT_FOUND";
251 + return false;
252 + }
253 +
254 + $openssl_algo = array_key_exists($sighshalgo, self::$SIG_HASH_ALGO_MAP) ? self::$SIG_HASH_ALGO_MAP[$sighshalgo] : null;
255 + if ($openssl_algo === null) {
256 + $this->error["message"] = "UNSUPPORTED_HASH_ALGORITHM: " . $sighshalgo;
257 + return false;
258 + }
259 +
260 + $key_file = dirname( __DIR__ ) . '/public_keys/' . $this->pubkey_name . '.pub';
261 + if (!file_exists($key_file)) {
262 + $this->error["message"] = "PUBLIC_KEY_NOT_FOUND";
263 + return false;
264 + }
265 +
266 + $public_key_str = WPRWPFileSystem::getInstance()->getContents($key_file);
267 +
268 + $public_key = openssl_pkey_get_public($public_key_str);
269 + if (!$public_key) {
270 + $this->error["message"] = "UNABLE_TO_LOAD_PUBLIC_KEY";
271 + return false;
272 + }
273 +
274 + $verify = openssl_verify($data, $sig, $public_key, $openssl_algo);
275 + if ($verify === 1) {
276 + return true;
277 + } elseif ($verify === 0) {
278 + $this->error["message"] = "INCORRECT_SIGNATURE";
279 + $this->error["pubkey_sig"] = substr(hash('md5', $public_key_str), 0, 8);
280 + } else {
281 + $this->error["message"] = "OPENSSL_VERIFY_FAILED";
282 + }
283 + return false;
284 + }
285 +
286 + public function corruptedParamsResp() {
287 + $bvinfo = new WPRInfo($this->settings);
288 +
289 + return array(
290 + "account_info" => $this->account->info(),
291 + "request_info" => $this->info(),
292 + "bvinfo" => $bvinfo->info(),
293 + "statusmsg" => "BVPRMS_CORRUPTED"
294 + );
295 + }
296 +
297 + public function authFailedResp() {
298 + $api_public_key = WPRAccount::getApiPublicKey($this->settings);
299 + $default_account_pubkey = WPRAccount::getDefaultPublicKey();
300 + $bvinfo = new WPRInfo($this->settings);
301 + $resp = array(
302 + "request_info" => $this->info(),
303 + "bvinfo" => $bvinfo->info(),
304 + "statusmsg" => "FAILED_AUTH",
305 + "api_pubkey" => substr($api_public_key, 0, 8)
306 + );
307 +
308 + if (is_string($default_account_pubkey) && strlen($default_account_pubkey) >= 32) {
309 + $resp["default_account_pubkey"] = substr($default_account_pubkey, 0, 8);
310 + }
311 +
312 + if ($this->account) {
313 + $resp["account_info"] = $this->account->info();
314 + } else {
315 + $resp["account_info"] = array("error" => "ACCOUNT_NOT_FOUND");
316 + }
317 +
318 + return $resp;
319 + }
220 320 }
221 -endif;
321 +endif;