Version Description
- Bug Fix: Fixed an issue where a user couldn't be unsynced if already removed from the dashboard
Download this release
Release Info
Developer | oakesjosh |
Plugin | iThemes Sync |
Version | 2.1.6 |
Comparing to | |
See all releases |
Code changes from version 2.1.5 to 2.1.6
- functions.php +53 -0
- history.txt +3 -1
- init.php +1 -1
- lang/ithemes-sync.pot +2 -2
- readme.txt +5 -2
- request-handler.php +46 -0
- server.php +11 -5
- settings-page.php +3 -2
functions.php
CHANGED
@@ -1030,4 +1030,57 @@ class Ithemes_Sync_Functions {
|
|
1030 |
return false;
|
1031 |
}
|
1032 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1033 |
}
|
1030 |
return false;
|
1031 |
}
|
1032 |
|
1033 |
+
/**
|
1034 |
+
* Checks if sodium library and methods we use are available
|
1035 |
+
* Also checks if sodium is fast enough on this system
|
1036 |
+
* If available: include the compatiability layer, core utilities, and Base64 UrlSafe classes
|
1037 |
+
*
|
1038 |
+
* @return bool
|
1039 |
+
*/
|
1040 |
+
public static function is_sodium_available() {
|
1041 |
+
$requiredFiles = array(
|
1042 |
+
'wp-includes/sodium_compat/autoload.php',
|
1043 |
+
);
|
1044 |
+
|
1045 |
+
foreach ( $requiredFiles as $file ) {
|
1046 |
+
if ( file_exists( ABSPATH . $file ) ) {
|
1047 |
+
require_once( ABSPATH . $file );
|
1048 |
+
} else {
|
1049 |
+
return false;
|
1050 |
+
}
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
// Verify the functions we need are callable
|
1054 |
+
if ( ! is_callable( 'sodium_base642bin' ) || ! is_callable( 'sodium_crypto_sign_verify_detached' ) ) {
|
1055 |
+
return false;
|
1056 |
+
}
|
1057 |
+
|
1058 |
+
// Check for a edge-case affecting PHP Maths abilities
|
1059 |
+
// Sodium_Compat isn't compatible with PHP 7.2.0~7.2.2 due to a bug in the PHP Opcache extension, bail early as it'll fail.
|
1060 |
+
if (
|
1061 |
+
! extension_loaded( 'sodium' ) &&
|
1062 |
+
in_array( PHP_VERSION_ID, [ 70200, 70201, 70202 ], true ) &&
|
1063 |
+
extension_loaded( 'opcache' )
|
1064 |
+
) {
|
1065 |
+
return false;
|
1066 |
+
}
|
1067 |
+
|
1068 |
+
// Verify runtime speed of Sodium_Compat is acceptable.
|
1069 |
+
if ( ! extension_loaded( 'sodium' ) && ! ParagonIE_Sodium_Compat::polyfill_is_fast() ) {
|
1070 |
+
|
1071 |
+
// Allow for an old version of Sodium_Compat being loaded before the bundled WordPress one.
|
1072 |
+
if ( method_exists( 'ParagonIE_Sodium_Compat', 'runtime_speed_test' ) ) {
|
1073 |
+
// Run `ParagonIE_Sodium_Compat::runtime_speed_test()` in optimized integer mode, as that's what is used for signing verifications.
|
1074 |
+
$old_fastMult = ParagonIE_Sodium_Compat::$fastMult;
|
1075 |
+
ParagonIE_Sodium_Compat::$fastMult = true;
|
1076 |
+
$sodium_compat_is_fast = ParagonIE_Sodium_Compat::runtime_speed_test( 100, 10 );
|
1077 |
+
ParagonIE_Sodium_Compat::$fastMult = $old_fastMult;
|
1078 |
+
|
1079 |
+
return $sodium_compat_is_fast;
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
}
|
1083 |
+
|
1084 |
+
return true;
|
1085 |
+
}
|
1086 |
}
|
history.txt
CHANGED
@@ -233,4 +233,6 @@
|
|
233 |
2.1.4.1 - 2020-03-17 - Josh Oakes
|
234 |
Bug Fix: Roll back public-key signed request support
|
235 |
2.1.5 - 2020-04-03 - Josh Oakes
|
236 |
-
Bug Fix: Limit the total number of unsent notices that can be queued
|
|
|
|
233 |
2.1.4.1 - 2020-03-17 - Josh Oakes
|
234 |
Bug Fix: Roll back public-key signed request support
|
235 |
2.1.5 - 2020-04-03 - Josh Oakes
|
236 |
+
Bug Fix: Limit the total number of unsent notices that can be queued
|
237 |
+
2.1.6 - 2020-05-20 - Josh Oakes
|
238 |
+
Bug Fix: Fixed an issue where a user couldn't be unsynced if already removed from the dashboard
|
init.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: iThemes Sync
|
|
4 |
Plugin URI: http://ithemes.com/sync
|
5 |
Description: Manage updates to your WordPress sites easily in one place.
|
6 |
Author: iThemes
|
7 |
-
Version: 2.1.
|
8 |
Author URI: http://ithemes.com/
|
9 |
Domain Path: /lang/
|
10 |
iThemes Package: ithemes-sync
|
4 |
Plugin URI: http://ithemes.com/sync
|
5 |
Description: Manage updates to your WordPress sites easily in one place.
|
6 |
Author: iThemes
|
7 |
+
Version: 2.1.6
|
8 |
Author URI: http://ithemes.com/
|
9 |
Domain Path: /lang/
|
10 |
iThemes Package: ithemes-sync
|
lang/ithemes-sync.pot
CHANGED
@@ -4,7 +4,7 @@ msgid ""
|
|
4 |
msgstr ""
|
5 |
"Project-Id-Version: iThemes Sync 2.1.5\n"
|
6 |
"Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
|
7 |
-
"POT-Creation-Date: 2020-
|
8 |
"PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=UTF-8\n"
|
@@ -350,7 +350,7 @@ msgstr ""
|
|
350 |
msgid "The Sync server returned an unknown response."
|
351 |
msgstr ""
|
352 |
|
353 |
-
#: server.php:
|
354 |
msgid "An unrecognized server response format was received from the iThemes Sync server."
|
355 |
msgstr ""
|
356 |
|
4 |
msgstr ""
|
5 |
"Project-Id-Version: iThemes Sync 2.1.5\n"
|
6 |
"Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
|
7 |
+
"POT-Creation-Date: 2020-05-20 20:44:47+00:00\n"
|
8 |
"PO-Revision-Date: 2020-MO-DA HO:MI+ZONE\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=UTF-8\n"
|
350 |
msgid "The Sync server returned an unknown response."
|
351 |
msgstr ""
|
352 |
|
353 |
+
#: server.php:195
|
354 |
msgid "An unrecognized server response format was received from the iThemes Sync server."
|
355 |
msgstr ""
|
356 |
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== iThemes Sync ===
|
2 |
-
Contributors: ithemes, layotte
|
3 |
Tags: manage multiple Sites, backup, security, migrate, SEO, manage updates, administration, update manager, reports, sync, google analytics, optimize, uptime, ithemes, customize dashboard, client sites, maintenance, management, google webmaster tools, reporting
|
4 |
Requires at least: 4.5
|
5 |
Requires PHP: 5.6
|
6 |
Tested up to: 5.4
|
7 |
-
Stable tag: 2.1.
|
8 |
License: GPLv3 or later
|
9 |
License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
|
10 |
|
@@ -87,6 +87,9 @@ Make steady, reliable income for WordPress maintenance with iThemes Sync Pro’s
|
|
87 |
|
88 |
== Changelog ==
|
89 |
|
|
|
|
|
|
|
90 |
= 2.1.5 =
|
91 |
* Bug Fix: Limit the total number of unsent notices that can be queued
|
92 |
|
1 |
=== iThemes Sync ===
|
2 |
+
Contributors: ithemes, layotte, oakesjosh
|
3 |
Tags: manage multiple Sites, backup, security, migrate, SEO, manage updates, administration, update manager, reports, sync, google analytics, optimize, uptime, ithemes, customize dashboard, client sites, maintenance, management, google webmaster tools, reporting
|
4 |
Requires at least: 4.5
|
5 |
Requires PHP: 5.6
|
6 |
Tested up to: 5.4
|
7 |
+
Stable tag: 2.1.6
|
8 |
License: GPLv3 or later
|
9 |
License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
|
10 |
|
87 |
|
88 |
== Changelog ==
|
89 |
|
90 |
+
= 2.1.6 =
|
91 |
+
* Bug Fix: Fixed an issue where a user couldn't be unsynced if already removed from the dashboard
|
92 |
+
|
93 |
= 2.1.5 =
|
94 |
* Bug Fix: Limit the total number of unsent notices that can be queued
|
95 |
|
request-handler.php
CHANGED
@@ -61,6 +61,25 @@ class Ithemes_Sync_Request_Handler {
|
|
61 |
|
62 |
$request = $_POST['request'];
|
63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
65 |
$request = stripslashes( $request );
|
66 |
}
|
@@ -461,6 +480,33 @@ class Ithemes_Sync_Request_Handler {
|
|
461 |
return $json;
|
462 |
}
|
463 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
464 |
}
|
465 |
|
466 |
new Ithemes_Sync_Request_Handler();
|
61 |
|
62 |
$request = $_POST['request'];
|
63 |
|
64 |
+
if ( !empty( $_POST['signature'] ) ) {
|
65 |
+
|
66 |
+
// Append success and failures to response
|
67 |
+
$sodium_available = Ithemes_Sync_Functions::is_sodium_available();
|
68 |
+
|
69 |
+
if ( $sodium_available && ! $this->verify_request_signature( $request, $_POST['signature'] ) ) {
|
70 |
+
// Sodium is available and verification failed
|
71 |
+
do_action( 'ithemes-sync-add-log', 'signature-verification', array( 'available' => true, 'verified' => false ) );
|
72 |
+
|
73 |
+
// $this->send_response( new WP_Error( 'request-signature-invalid', 'The request signature could not be verified' ) );
|
74 |
+
} elseif ( $sodium_available ) {
|
75 |
+
// Sodium available and signature was verified
|
76 |
+
do_action( 'ithemes-sync-add-log', 'signature-verification', array( 'available' => true, 'verified' => true ) );
|
77 |
+
} else {
|
78 |
+
// Sodium is not available
|
79 |
+
do_action( 'ithemes-sync-add-log', 'signature-verification', array( 'available' => false, 'verified' => false ) );
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
84 |
$request = stripslashes( $request );
|
85 |
}
|
480 |
return $json;
|
481 |
}
|
482 |
|
483 |
+
/**
|
484 |
+
* Determine if signature supplied in the request can be verified using the public key
|
485 |
+
*
|
486 |
+
* @param $request
|
487 |
+
* @param $signature
|
488 |
+
*
|
489 |
+
* @return bool
|
490 |
+
*/
|
491 |
+
private function verify_request_signature( $request, $signature ) {
|
492 |
+
|
493 |
+
// Verify the functions we need are callable
|
494 |
+
if ( ! is_callable( 'sodium_base642bin' ) || ! is_callable( 'sodium_crypto_sign_verify_detached' ) ) {
|
495 |
+
return false;
|
496 |
+
}
|
497 |
+
|
498 |
+
try {
|
499 |
+
|
500 |
+
$public_key = sodium_base642bin( file_get_contents( $GLOBALS['ithemes_sync_path'] . '/public.key' ), 5 );
|
501 |
+
$signature = sodium_base642bin( $signature, 5 );
|
502 |
+
|
503 |
+
} catch ( Exception $e ) {
|
504 |
+
return false;
|
505 |
+
}
|
506 |
+
|
507 |
+
return sodium_crypto_sign_verify_detached( $signature, $request, $public_key );
|
508 |
+
}
|
509 |
+
|
510 |
}
|
511 |
|
512 |
new Ithemes_Sync_Request_Handler();
|
server.php
CHANGED
@@ -110,6 +110,9 @@ class Ithemes_Sync_Server {
|
|
110 |
}
|
111 |
|
112 |
public static function request( $action, $query = array(), $data = array() ) {
|
|
|
|
|
|
|
113 |
if ( isset( $data['auth_token'] ) ) {
|
114 |
$data['iterations'] = self::$password_iterations;
|
115 |
}
|
@@ -152,13 +155,13 @@ class Ithemes_Sync_Server {
|
|
152 |
$response = self::do_patched_post( $request, $remote_post_args );
|
153 |
|
154 |
if ( is_wp_error( $response ) ) {
|
155 |
-
$response = wp_remote_post(
|
156 |
} else {
|
157 |
$options['use_ca_patch'] = true;
|
158 |
}
|
159 |
}
|
160 |
else {
|
161 |
-
$response = wp_remote_post(
|
162 |
|
163 |
if ( is_wp_error( $response ) ) {
|
164 |
$response = self::do_patched_post( $request, $remote_post_args );
|
@@ -170,7 +173,7 @@ class Ithemes_Sync_Server {
|
|
170 |
}
|
171 |
|
172 |
if ( is_wp_error( $response ) ) {
|
173 |
-
$response = wp_remote_post(
|
174 |
|
175 |
$options['use_ssl'] = false;
|
176 |
$options['use_ca_patch'] = false;
|
@@ -201,8 +204,10 @@ class Ithemes_Sync_Server {
|
|
201 |
}
|
202 |
|
203 |
private static function do_patched_post( $request, $remote_post_args ) {
|
|
|
|
|
204 |
self::enable_ssl_ca_patch();
|
205 |
-
$response = wp_remote_post(
|
206 |
self::disable_ssl_ca_patch();
|
207 |
|
208 |
return $response;
|
@@ -224,9 +229,10 @@ class Ithemes_Sync_Server {
|
|
224 |
}
|
225 |
|
226 |
public static function add_ca_patch_to_curl_opts( $handle ) {
|
|
|
227 |
$url = curl_getinfo( $handle, CURLINFO_EFFECTIVE_URL );
|
228 |
|
229 |
-
if ( ! preg_match( '/^' . preg_quote(
|
230 |
return;
|
231 |
}
|
232 |
|
110 |
}
|
111 |
|
112 |
public static function request( $action, $query = array(), $data = array() ) {
|
113 |
+
|
114 |
+
$secure_url = apply_filters( 'sync_api_request_url', self::$secure_server_url );
|
115 |
+
|
116 |
if ( isset( $data['auth_token'] ) ) {
|
117 |
$data['iterations'] = self::$password_iterations;
|
118 |
}
|
155 |
$response = self::do_patched_post( $request, $remote_post_args );
|
156 |
|
157 |
if ( is_wp_error( $response ) ) {
|
158 |
+
$response = wp_remote_post( $secure_url . $request, $remote_post_args );
|
159 |
} else {
|
160 |
$options['use_ca_patch'] = true;
|
161 |
}
|
162 |
}
|
163 |
else {
|
164 |
+
$response = wp_remote_post( $secure_url . $request, $remote_post_args );
|
165 |
|
166 |
if ( is_wp_error( $response ) ) {
|
167 |
$response = self::do_patched_post( $request, $remote_post_args );
|
173 |
}
|
174 |
|
175 |
if ( is_wp_error( $response ) ) {
|
176 |
+
$response = wp_remote_post( $secure_url . $request . '&insecure=1', $remote_post_args );
|
177 |
|
178 |
$options['use_ssl'] = false;
|
179 |
$options['use_ca_patch'] = false;
|
204 |
}
|
205 |
|
206 |
private static function do_patched_post( $request, $remote_post_args ) {
|
207 |
+
$secure_url = apply_filters( 'sync_api_request_url', self::$secure_server_url );
|
208 |
+
|
209 |
self::enable_ssl_ca_patch();
|
210 |
+
$response = wp_remote_post( $secure_url . $request . '&ca_patch=1', $remote_post_args );
|
211 |
self::disable_ssl_ca_patch();
|
212 |
|
213 |
return $response;
|
229 |
}
|
230 |
|
231 |
public static function add_ca_patch_to_curl_opts( $handle ) {
|
232 |
+
$secure_url = apply_filters( 'sync_api_request_url', self::$secure_server_url );
|
233 |
$url = curl_getinfo( $handle, CURLINFO_EFFECTIVE_URL );
|
234 |
|
235 |
+
if ( ! preg_match( '/^' . preg_quote( $secure_url, '/' ) . '/', $url ) ) {
|
236 |
return;
|
237 |
}
|
238 |
|
settings-page.php
CHANGED
@@ -155,8 +155,8 @@ class Ithemes_Sync_Settings_Page {
|
|
155 |
|
156 |
|
157 |
$result = Ithemes_Sync_Server::deauthenticate( $data['user'], $user_details['username'], $user_details['key'] );
|
158 |
-
|
159 |
-
if ( is_wp_error( $result ) && ( 'authentication' != $result->get_error_code() ) ) {
|
160 |
$heading = __( 'The user could not be unsynced.', 'it-l10n-ithemes-sync' );
|
161 |
$message = $result->get_error_message();
|
162 |
|
@@ -336,6 +336,7 @@ class Ithemes_Sync_Settings_Page {
|
|
336 |
<?php wp_nonce_field( 'authenticate-user' ); ?>
|
337 |
</form>
|
338 |
</div>
|
|
|
339 |
</div>
|
340 |
<?php
|
341 |
|
155 |
|
156 |
|
157 |
$result = Ithemes_Sync_Server::deauthenticate( $data['user'], $user_details['username'], $user_details['key'] );
|
158 |
+
|
159 |
+
if ( is_wp_error( $result ) && ( 'authentication' != $result->get_error_code() ) && 'This site has not been authenticated by this user.' != $result->get_error_message() ) {
|
160 |
$heading = __( 'The user could not be unsynced.', 'it-l10n-ithemes-sync' );
|
161 |
$message = $result->get_error_message();
|
162 |
|
336 |
<?php wp_nonce_field( 'authenticate-user' ); ?>
|
337 |
</form>
|
338 |
</div>
|
339 |
+
<?php do_action('sync_dev_render'); ?>
|
340 |
</div>
|
341 |
<?php
|
342 |
|