PluginProbe
The WP Remote WordPress Plugin / 5.22
The WP Remote WordPress Plugin v5.22
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.22, at callback/request.php

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