PluginProbe
The WP Remote WordPress Plugin / 5.93
The WP Remote WordPress Plugin v5.93
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
wpremote / callback / request.php

request.php in The WP Remote WordPress Plugin 5.93, at callback/request.php

307 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) exit;
4 if (!class_exists('BVCallbackRequest')) :
5 class BVCallbackRequest {
6 public $params;
7 public $method;
8 public $wing;
9 public $is_afterload;
10 public $is_admin_ajax;
11 public $is_debug;
12 public $account;
13 public $settings;
14 public $sig;
15 public $sighshalgo;
16 public $time;
17 public $version;
18 public $is_sha1;
19 public $bvb64stream;
20 public $bvb64cksize;
21 public $checksum;
22 public $error = array();
23 public $pubkey_name;
24 public $bvprmsmac;
25 public $bvboundry;
26
27 public function __construct($account, $in_params, $settings) {
28 $this->params = array();
29 $this->account = $account;
30 $this->settings = $settings;
31 $this->wing = $in_params['wing'];
32 $this->method = $in_params['bvMethod'];
33 $this->is_afterload = array_key_exists('afterload', $in_params);
34 $this->is_admin_ajax = array_key_exists('adajx', $in_params);
35 $this->is_debug = array_key_exists('bvdbg', $in_params);
36 $this->sig = $in_params['sig'];
37 $this->sighshalgo = !empty($in_params['sighshalgo']) ? $in_params['sighshalgo'] : null;
38 $this->time = intval($in_params['bvTime']);
39 $this->version = $in_params['bvVersion'];
40 $this->is_sha1 = array_key_exists('sha1', $in_params);
41 $this->bvb64stream = isset($in_params['bvb64stream']);
42 $this->bvb64cksize = array_key_exists('bvb64cksize', $in_params) ? intval($in_params['bvb64cksize']) : false;
43 $this->checksum = array_key_exists('checksum', $in_params) ? $in_params['checksum'] : false;
44 $this->pubkey_name = !empty($in_params['pubkeyname']) ?
45 WPRAccount::sanitizeKey($in_params['pubkeyname']) : 'm_public';
46 $this->bvprmsmac = !empty($in_params['bvprmsmac']) ? WPRAccount::sanitizeKey($in_params['bvprmsmac']) : "";
47 $this->bvboundry = !empty($in_params['bvboundry']) ? $in_params['bvboundry'] : "";
48 }
49
50 public function isAPICall() {
51 return array_key_exists('apicall', $this->params);
52 }
53
54 public function http_request($url, $body) {
55 $body = http_build_query($body);
56 $response = wp_remote_post($url, array(
57 'body' => $body,
58 'timeout' => 15,
59 'headers' => array(
60 'Content-Type' => 'application/x-www-form-urlencoded',
61 ),
62 ));
63
64 if (is_wp_error($response)) {
65 return false;
66 }
67
68 return wp_remote_retrieve_body($response);
69 }
70
71 public function get_params_via_api($params_key, $apiurl) {
72 $res = $this->http_request($apiurl, array('bvkey' => $params_key));
73
74 if ($res === FALSE) {
75 return false;
76 }
77
78 return $res;
79 }
80
81 public function info() {
82 $info = array(
83 "requestedsig" => $this->sig,
84 "requestedtime" => $this->time,
85 "requestedversion" => $this->version,
86 "error" => $this->error
87 );
88 if ($this->is_debug) {
89 $info["inreq"] = $this->params;
90 }
91 if ($this->is_admin_ajax) {
92 $info["adajx"] = true;
93 }
94 if ($this->is_afterload) {
95 $info["afterload"] = true;
96 }
97 return $info;
98 }
99
100 public function processParams($in_params) {
101 $params = array();
102
103 if (array_key_exists('obend', $in_params) && function_exists('ob_end_clean'))
104 @ob_end_clean();
105
106 if (array_key_exists('op_reset', $in_params) && function_exists('output_reset_rewrite_vars'))
107 @output_reset_rewrite_vars();
108
109 if (array_key_exists('concat', $in_params)) {
110 foreach ($in_params['concat'] as $key) {
111 $concated = '';
112 $count = intval($in_params[$key]);
113 for ($i = 1; $i <= $count; $i++) {
114 $concated .= $in_params[$key."_bv_".$i];
115 }
116 $in_params[$key] = $concated;
117 }
118 }
119
120 if (isset($in_params['bvpdataviaapi']) && isset($in_params['bvapiurl'])) {
121 $pdata = $this->get_params_via_api($in_params['bvpdataviaapi'], $in_params['bvapiurl']);
122 if ($pdata !== false) {
123 $in_params["bvprms"] = $pdata;
124 }
125 }
126
127 if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
128 if (!empty($in_params['bvprmshshalgo']) && $in_params['bvprmshshalgo'] === 'sha256') {
129 $calculated_mac = hash_hmac('SHA256', $in_params['bvprms'], $this->account->secret);
130 } else {
131 $calculated_mac = hash_hmac('SHA1', $in_params['bvprms'], $this->account->secret);
132 }
133
134 if ($this->compare_mac($this->bvprmsmac, $calculated_mac) === true) {
135
136 if (array_key_exists('b64', $in_params)) {
137 foreach ($in_params['b64'] as $key) {
138 if (is_array($in_params[$key])) {
139 $in_params[$key] = array_map('base64_decode', $in_params[$key]);
140 } else {
141 $in_params[$key] = base64_decode($in_params[$key]);
142 }
143 }
144 }
145
146 if (array_key_exists('unser', $in_params)) {
147 foreach ($in_params['unser'] as $key) {
148 $in_params[$key] = json_decode($in_params[$key], TRUE);
149 }
150 }
151
152 if (array_key_exists('sersafe', $in_params)) {
153 $key = $in_params['sersafe'];
154 $in_params[$key] = BVCallbackRequest::serialization_safe_decode($in_params[$key]);
155 }
156
157 if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
158 $params = $in_params['bvprms'];
159 }
160
161 if (array_key_exists('clacts', $in_params)) {
162 foreach ($in_params['clacts'] as $action) {
163 remove_all_actions($action);
164 }
165 }
166
167 if (array_key_exists('clallacts', $in_params)) {
168 global $wp_filter;
169 foreach ( $wp_filter as $filter => $val ){
170 remove_all_actions($filter);
171 }
172 }
173
174 if (array_key_exists('memset', $in_params)) {
175 $val = intval($in_params['memset']);
176 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for memory limit adjustment
177 @ini_set('memory_limit', $val.'M');
178 }
179
180 return $params;
181 }
182 }
183 return false;
184 }
185
186 private function compare_mac($l_hash, $r_hash) {
187 if (!is_string($l_hash) || !is_string($r_hash)) {
188 return false;
189 }
190
191 if (strlen($l_hash) !== strlen($r_hash)) {
192 return false;
193 }
194
195 if (function_exists('hash_equals')) {
196 return hash_equals($l_hash, $r_hash);
197 } else {
198 return $l_hash === $r_hash;
199 }
200 }
201
202 public static function serialization_safe_decode($data) {
203 if (is_array($data)) {
204 $data = array_map(array('BVCallbackRequest', 'serialization_safe_decode'), $data);
205 } elseif (is_string($data)) {
206 $data = base64_decode($data);
207 }
208
209 return $data;
210 }
211
212 public function authenticate() {
213 if (!$this->account) {
214 $this->error["message"] = "ACCOUNT_NOT_FOUND";
215 return false;
216 }
217
218 $bv_last_recv_time = $this->settings->getOption('bvLastRecvTime');
219 if ($this->time < intval($bv_last_recv_time) - 300) {
220 return false;
221 }
222
223 $data = $this->method.$this->account->secret.$this->time.$this->version.$this->bvprmsmac;
224 if (!$this->verify($data, base64_decode($this->sig), $this->sighshalgo)) {
225 return false;
226 }
227 $this->settings->updateOption('bvLastRecvTime', $this->time);
228
229 return 1;
230 }
231
232 public function verify($data, $sig, $sighshalgo) {
233 if (!function_exists('openssl_verify') || !function_exists('openssl_pkey_get_public')) {
234 $this->error["message"] = "OPENSSL_FUNCS_NOT_FOUND";
235 return false;
236 }
237
238 $key_file = dirname( __DIR__ ) . '/public_keys/' . $this->pubkey_name . '.pub';
239 if (!file_exists($key_file)) {
240 $this->error["message"] = "PUBLIC_KEY_NOT_FOUND";
241 return false;
242 }
243
244 $public_key_str = WPRWPFileSystem::getInstance()->getContents($key_file);
245
246 $public_key = openssl_pkey_get_public($public_key_str);
247 if (!$public_key) {
248 $this->error["message"] = "UNABLE_TO_LOAD_PUBLIC_KEY";
249 return false;
250 }
251
252 if ($sighshalgo === 'sha256') {
253 $verify = openssl_verify($data, $sig, $public_key, OPENSSL_ALGO_SHA256);
254 } else {
255 $verify = openssl_verify($data, $sig, $public_key);
256 }
257 if ($verify === 1) {
258 return true;
259 } elseif ($verify === 0) {
260 $this->error["message"] = "INCORRECT_SIGNATURE";
261 $this->error["pubkey_sig"] = substr(hash('md5', $public_key_str), 0, 8);
262 } else {
263 $this->error["message"] = "OPENSSL_VERIFY_FAILED";
264 }
265 return false;
266 }
267
268 public function corruptedParamsResp() {
269 $bvinfo = new WPRInfo($this->settings);
270
271 return array(
272 "account_info" => $this->account->info(),
273 "request_info" => $this->info(),
274 "bvinfo" => $bvinfo->info(),
275 "statusmsg" => "BVPRMS_CORRUPTED"
276 );
277 }
278
279 public function authFailedResp() {
280 $api_public_key = WPRAccount::getApiPublicKey($this->settings);
281 $default_secret = WPRRecover::getDefaultSecret($this->settings);
282 $default_account_pubkey = WPRAccount::getDefaultPublicKey();
283 $bvinfo = new WPRInfo($this->settings);
284 $resp = array(
285 "request_info" => $this->info(),
286 "bvinfo" => $bvinfo->info(),
287 "statusmsg" => "FAILED_AUTH",
288 "api_pubkey" => substr($api_public_key, 0, 8),
289 "def_key_status" => WPRRecover::getSecretStatus($this->settings),
290 "def_sigmatch" => substr(hash('sha1', $this->method.$default_secret.$this->time.$this->version), 0, 8)
291 );
292
293 if (is_string($default_account_pubkey) && strlen($default_account_pubkey) >= 32) {
294 $resp["default_account_pubkey"] = substr($default_account_pubkey, 0, 8);
295 }
296
297 if ($this->account) {
298 $resp["account_info"] = $this->account->info();
299 $resp["sigmatch"] = substr(hash('sha1', $this->method.$this->account->secret.$this->time.$this->version), 0, 6);
300 } else {
301 $resp["account_info"] = array("error" => "ACCOUNT_NOT_FOUND");
302 }
303
304 return $resp;
305 }
306 }
307 endif;