PluginProbe
Patchstack – WordPress & Plugins Security / 2.2.2
Patchstack – WordPress & Plugins Security v2.2.2
2.3.7 trunk 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.17 2.1.18 2.1.19 2.1.2 2.1.20 2.1.21 2.1.22 2.1.23 2.1.24 2.1.25 2.1.3 2.1.4 2.1.5 2.1.6 All 49 releases
← All changes | includes/api.php +82 -35 2.1.132.2.2 View file →
@@ -23,10 +23,10 @@
23 23 */
24 24 public function __construct( $core ) {
25 25 parent::__construct( $core );
26 26 $this->blog_id = get_current_blog_id();
27 - add_action( 'patchstack_update_license_status', array( $this, 'update_license_status' ) );
28 - add_action( 'patchstack_send_ping', array( $this, 'ping' ) );
27 + add_action( 'patchstack_update_license_status', [ $this, 'update_license_status' ] );
28 + add_action( 'patchstack_send_ping', [ $this, 'ping' ] );
29 29 }
30 30
31 31 /**
32 32 * Get the API token.
@@ -50,12 +50,12 @@
50 50 if ( $response && $response->result == 'success' ) {
51 51 $this->update_blog_option(
52 52 $this->blog_id,
53 53 'patchstack_api_token',
54 - array(
54 + [
55 55 'token' => $response->message,
56 56 'expiresin' => $response->expiresin,
57 - )
57 + ]
58 58 );
59 59 return $response->message;
60 60 }
61 61
@@ -72,17 +72,25 @@
72 72 * @return string|array
73 73 */
74 74 public function fetch_access_token( $clientid = '', $secretkey = '' ) {
75 75 // Skeleton for the response data.
76 - $response_data = (object) array(
76 + $response_data = (object) [
77 77 'result' => '',
78 78 'message' => '',
79 79 'expiresin' => '',
80 - );
80 + ];
81 81
82 82 // Determine if the license id/key is set.
83 - $client_id = $this->get_blog_option( $this->blog_id, 'patchstack_clientid', false ) ? $this->get_blog_option( $this->blog_id, 'patchstack_clientid', false ) : $clientid;
84 - $client_secret = $this->get_blog_option( $this->blog_id, 'patchstack_secretkey', false ) ? $this->get_blog_option( $this->blog_id, 'patchstack_secretkey', false ) : $secretkey;
83 + $client_id = $this->get_blog_option( $this->blog_id, 'patchstack_clientid', $clientid );
84 +
85 + // Decrypt the secret key, if it is encrypted.
86 + $client_secret = $this->get_blog_option( $this->blog_id, 'patchstack_secretkey', $secretkey );
87 + $client_nonce = $this->get_blog_option( $this->blog_id, 'patchstack_secretkey_nonce', false );
88 + if ( $client_nonce ) {
89 + $client_secret = $this->decrypt( $client_secret, $client_nonce );
90 + }
91 +
92 + // Make sure these values are set.
85 93 if ( empty( $client_id ) || empty( $client_secret ) ) {
86 94 $response_data->result = 'failed';
87 95 $response_data->message = __( 'API keys missing! Unable to obtain an access token.', 'patchstack' );
88 96 return $response_data;
@@ -90,22 +98,22 @@
90 98
91 99 // Send a request to our server to obtain the access token.
92 100 $response = wp_remote_post(
93 101 $this->plugin->auth_url . '/oauth/token',
94 - array(
102 + [
95 103 'method' => 'POST',
96 104 'timeout' => 60,
97 105 'redirection' => 5,
98 106 'httpversion' => '1.0',
99 107 'blocking' => true,
100 - 'headers' => array(),
101 - 'body' => array(
108 + 'headers' => [],
109 + 'body' => [
102 110 'client_id' => $client_id,
103 111 'client_secret' => $client_secret,
104 112 'grant_type' => 'client_credentials',
105 - ),
106 - 'cookies' => array(),
107 - )
113 + ],
114 + 'cookies' => [],
115 + ]
108 116 );
109 117
110 118 // Stop if we received an error from the API.
111 119 if ( is_wp_error( $response ) ) {
@@ -128,17 +136,10 @@
128 136 $response_data->message = 'expires_in value must be an integer';
129 137 return $response_data;
130 138 }
131 139 $response_data->expiresin = $result->expires_in != 0 ? time() + $result->expires_in : 0;
132 - } elseif ( ! empty( $result->expires_in ) ) {
133 - // Some providers supply the seconds until expiration rather than
134 - // the exact timestamp. Take a best guess at which we received.
135 - $expires = $options['expires'];
136 - if ( ! $this->isExpirationTimestamp( $expires ) ) {
137 - $expires += time();
138 - }
139 - $response_data->expiresin = $expires;
140 140 }
141 +
141 142 return $response_data;
142 143 } elseif ( isset( $result->error ) ) {
143 144 $response_data->result = $result->error;
144 145 $response_data->message = __( 'Unexpected error! Unable to obtain an access token.', 'patchstack' ) . $result->message;
@@ -174,8 +175,10 @@
174 175 $this->update_blog_option( $this->blog_id, 'patchstack_license_free', $response['free'] == false ? 0 : 1 );
175 176
176 177 if ( $response['free'] == true ) {
177 178 $this->update_blog_option( $this->blog_id, 'patchstack_show_settings', 0 );
179 + } else {
180 + $this->send_header_request();
178 181 }
179 182 }
180 183
181 184 if ( isset( $response['active'] ) && $response['active'] == true ) {
@@ -181,8 +184,22 @@
181 184 if ( isset( $response['active'] ) && $response['active'] == true ) {
182 185 $this->update_blog_option( $this->blog_id, 'patchstack_license_activated', true );
183 186 }
184 187
188 + if ( isset( $response['class'] ) ) {
189 + $this->update_blog_option( $this->blog_id, 'patchstack_subscription_class', $response['class'] );
190 + $this->update_blog_option( $this->blog_id, 'patchstack_last_license_check', time() );
191 + }
192 +
193 + if ( isset( $response['managed'], $response['managed_string'] ) ) {
194 + $this->update_blog_option( $this->blog_id, 'patchstack_managed', $response['managed'] );
195 + $this->update_blog_option( $this->blog_id, 'patchstack_managed_text', $response['managed_string'] );
196 + }
197 +
198 + if ( isset( $response['site_id'] ) ) {
199 + $this->update_blog_option( $this->blog_id, 'patchstack_site_id', $response['site_id'] );
200 + }
201 +
185 202 return $response;
186 203 }
187 204
188 205 /**
@@ -192,9 +209,9 @@
192 209 * @param string $request
193 210 * @param array $data
194 211 * @return void|array If successful array, otherwise void.
195 212 */
196 - public function send_request( $url, $request, $data = array() ) {
213 + public function send_request( $url, $request, $data = [] ) {
197 214 // Attempt to get the access token.
198 215 $token = $this->get_access_token();
199 216 if ( empty( $token ) ) {
200 217 return;
@@ -202,22 +219,22 @@
202 219
203 220 // Send the remote request using the WordPress built-in method.
204 221 $response = wp_remote_request(
205 222 $this->plugin->api_url . $url,
206 - array(
223 + [
207 224 'method' => $request,
208 225 'timeout' => 60,
209 226 'redirection' => 5,
210 227 'httpversion' => '1.0',
211 228 'blocking' => true,
212 - 'headers' => array(
229 + 'headers' => [
213 230 'Authorization' => 'Bearer ' . $token,
214 231 'LicenseID' => $this->get_blog_option( $this->blog_id, 'patchstack_clientid', 0 ),
215 232 'Source-Host' => get_site_url(),
216 - ),
233 + ],
217 234 'body' => $data,
218 - 'cookies' => array(),
219 - )
235 + 'cookies' => [],
236 + ]
220 237 );
221 238
222 239 // Check error or status code.
223 240 if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) != 200 ) {
@@ -228,19 +245,49 @@
228 245 return json_decode( wp_remote_retrieve_body( $response ), true );
229 246 }
230 247
231 248 /**
249 + * Send a request to our API for the IP address header.
250 + */
251 + public function send_header_request()
252 + {
253 + $header = get_option( 'patchstack_firewall_ip_header', '' );
254 + $computed = get_option( 'patchstack_ip_header_computed', 0 );
255 +
256 + if ( $header == '' && ! $computed ) {
257 + // Create an OTT token.
258 + $ott = md5( wp_generate_password( 32, true, true ) );
259 + update_option( 'patchstack_ott_action', $ott );
260 +
261 + // Tell our API.
262 + wp_remote_request(
263 + $this->plugin->api_url . '/api/header',
264 + [
265 + 'method' => 'POST',
266 + 'timeout' => 60,
267 + 'redirection' => 5,
268 + 'httpversion' => '1.0',
269 + 'blocking' => true,
270 + 'headers' => [
271 + 'Source-Host' => get_site_url(),
272 + ],
273 + 'body' => [
274 + 'token' => $ott,
275 + 'url' => get_site_url()
276 + ],
277 + 'cookies' => [],
278 + ]
279 + );
280 + }
281 + }
282 +
283 + /**
232 284 * Get the firewall rules.
233 285 *
234 286 * @return array The firewall rules.
235 287 */
236 288 public function post_firewall_rule_json() {
237 - // If the request is coming from the API, fetch fresh rules.
238 - if ( isset( $_POST['webarx_refresh_rules'] ) ) {
239 - return $this->send_request( '/api/get-rules/2?bypass=cache', 'POST' );
240 - }
241 -
242 - return $this->send_request( '/api/get-rules/2', 'POST' );
289 + return $this->send_request( '/api/get-rules/3', 'POST' );
243 290 }
244 291
245 292 /**
246 293 * Get the .htaccess rules.
@@ -330,7 +377,7 @@
330 377 *
331 378 * @return void
332 379 */
333 380 public function ping() {
334 - $this->send_request( '/api/ping', 'POST', array( 'firewall' => $this->get_option( 'patchstack_basic_firewall' ) == 1 ? 1 : 0 ) );
381 + $this->send_request( '/api/ping', 'POST', [ 'firewall' => $this->get_option( 'patchstack_basic_firewall' ) == 1 ? 1 : 0 ] );
335 382 }
336 383 }