Version Description
- Enhancement: Added support for public-key signed requests to the plugin
Download this release
Release Info
Developer | layotte |
Plugin | iThemes Sync |
Version | 2.1.4 |
Comparing to | |
See all releases |
Code changes from version 2.1.3.1 to 2.1.4
- functions.php +51 -0
- history.txt +2 -0
- init.php +1 -1
- lang/ithemes-sync.pot +2 -2
- public.key +1 -0
- readme.txt +4 -1
- request-handler.php +63 -24
functions.php
CHANGED
@@ -1029,4 +1029,55 @@ class Ithemes_Sync_Functions {
|
|
1029 |
|
1030 |
return false;
|
1031 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1032 |
}
|
1029 |
|
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/src/Compat.php',
|
1043 |
+
'wp-includes/sodium_compat/src/Core/Base64/UrlSafe.php',
|
1044 |
+
'wp-includes/sodium_compat/src/Core/Util.php'
|
1045 |
+
);
|
1046 |
+
|
1047 |
+
foreach ( $requiredFiles as $file ) {
|
1048 |
+
if ( file_exists( ABSPATH . $file ) ) {
|
1049 |
+
require_once( ABSPATH . $file );
|
1050 |
+
} else {
|
1051 |
+
return false;
|
1052 |
+
}
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
// Check for a edge-case affecting PHP Maths abilities
|
1056 |
+
// 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.
|
1057 |
+
if (
|
1058 |
+
! extension_loaded( 'sodium' ) &&
|
1059 |
+
in_array( PHP_VERSION_ID, [ 70200, 70201, 70202 ], true ) &&
|
1060 |
+
extension_loaded( 'opcache' )
|
1061 |
+
) {
|
1062 |
+
return false;
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
// Verify runtime speed of Sodium_Compat is acceptable.
|
1066 |
+
if ( ! extension_loaded( 'sodium' ) && ! ParagonIE_Sodium_Compat::polyfill_is_fast() ) {
|
1067 |
+
|
1068 |
+
// Allow for an old version of Sodium_Compat being loaded before the bundled WordPress one.
|
1069 |
+
if ( method_exists( 'ParagonIE_Sodium_Compat', 'runtime_speed_test' ) ) {
|
1070 |
+
// Run `ParagonIE_Sodium_Compat::runtime_speed_test()` in optimized integer mode, as that's what is used for signing verifications.
|
1071 |
+
$old_fastMult = ParagonIE_Sodium_Compat::$fastMult;
|
1072 |
+
ParagonIE_Sodium_Compat::$fastMult = true;
|
1073 |
+
$sodium_compat_is_fast = ParagonIE_Sodium_Compat::runtime_speed_test( 100, 10 );
|
1074 |
+
ParagonIE_Sodium_Compat::$fastMult = $old_fastMult;
|
1075 |
+
|
1076 |
+
return $sodium_compat_is_fast;
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
return true;
|
1082 |
+
}
|
1083 |
}
|
history.txt
CHANGED
@@ -228,3 +228,5 @@
|
|
228 |
Bug Fix: Add nonce to authentication request
|
229 |
2.1.3.1 - 2020-02-18 - Lew Ayotte
|
230 |
Forgot to update the stable tag from last update
|
|
|
|
228 |
Bug Fix: Add nonce to authentication request
|
229 |
2.1.3.1 - 2020-02-18 - Lew Ayotte
|
230 |
Forgot to update the stable tag from last update
|
231 |
+
2.1.4 - 2020-03-16 - Josh Oakes
|
232 |
+
Enhancement: Added support for public-key signed requests to the plugin
|
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.4
|
8 |
Author URI: http://ithemes.com/
|
9 |
Domain Path: /lang/
|
10 |
iThemes Package: ithemes-sync
|
lang/ithemes-sync.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the same license as the iThemes Sync package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: iThemes Sync 2.1.
|
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"
|
2 |
# This file is distributed under the same license as the iThemes Sync package.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: iThemes Sync 2.1.4\n"
|
6 |
"Report-Msgid-Bugs-To: http://ithemes.com/support/\n"
|
7 |
+
"POT-Creation-Date: 2020-03-17 14:06:40+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"
|
public.key
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
HW1bf2OWXmTKogDwNk76mLng2ULL8v7lUXpDLdqUMWE=
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: manage multiple Sites, backup, security, migrate, SEO, manage updates, adm
|
|
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.3.1 =
|
91 |
* Updating stable tag
|
92 |
|
4 |
Requires at least: 4.5
|
5 |
Requires PHP: 5.6
|
6 |
Tested up to: 5.4
|
7 |
+
Stable tag: 2.1.4
|
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.4 =
|
91 |
+
* Enhancement: Added support for public-key signed requests to the plugin
|
92 |
+
|
93 |
= 2.1.3.1 =
|
94 |
* Updating stable tag
|
95 |
|
request-handler.php
CHANGED
@@ -35,6 +35,7 @@ Version History
|
|
35 |
|
36 |
|
37 |
require_once( $GLOBALS['ithemes_sync_path'] . '/load-translations.php' );
|
|
|
38 |
|
39 |
class Ithemes_Sync_Request_Handler {
|
40 |
private $logs = array();
|
@@ -45,14 +46,40 @@ class Ithemes_Sync_Request_Handler {
|
|
45 |
|
46 |
public function __construct() {
|
47 |
$this->show_errors();
|
48 |
-
|
49 |
-
|
50 |
if ( empty( $_POST['request'] ) ) {
|
51 |
return;
|
52 |
}
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
|
57 |
$request = stripslashes( $request );
|
58 |
}
|
@@ -62,20 +89,9 @@ class Ithemes_Sync_Request_Handler {
|
|
62 |
if ( ! is_array( $request ) ) {
|
63 |
return;
|
64 |
}
|
65 |
-
|
66 |
-
|
67 |
$GLOBALS['ithemes_sync_request_handler'] = $this;
|
68 |
-
|
69 |
-
|
70 |
-
add_action( 'ithemes-sync-add-log', array( $this, 'add_log' ), 10, 2 );
|
71 |
-
add_action( 'shutdown', array( $this, 'handle_error' ) );
|
72 |
-
|
73 |
-
add_action( 'ithemes_sync_verbs_registered', array( $this, 'handle_request' ) );
|
74 |
-
|
75 |
-
require_once( $GLOBALS['ithemes_sync_path'] . '/api.php' );
|
76 |
-
require_once( $GLOBALS['ithemes_sync_path'] . '/functions.php' );
|
77 |
-
require_once( $GLOBALS['ithemes_sync_path'] . '/settings.php' );
|
78 |
-
|
79 |
$this->options = $GLOBALS['ithemes-sync-settings']->get_options();
|
80 |
|
81 |
$this->parse_request( $request );
|
@@ -277,15 +293,15 @@ class Ithemes_Sync_Request_Handler {
|
|
277 |
|
278 |
public function send_response( $data ) {
|
279 |
if ( is_wp_error( $data ) ) {
|
280 |
-
foreach ( $data->get_error_codes() as $code )
|
281 |
-
$response['errors'][$code] = $data->get_error_message( $code );
|
282 |
-
|
283 |
-
else {
|
284 |
$response = array(
|
285 |
'response' => $data,
|
286 |
);
|
287 |
}
|
288 |
-
|
289 |
if ( ! empty( $this->logs ) ) {
|
290 |
$response['logs'] = $this->logs;
|
291 |
}
|
@@ -436,7 +452,7 @@ class Ithemes_Sync_Request_Handler {
|
|
436 |
|
437 |
$this->logs[] = $log;
|
438 |
}
|
439 |
-
|
440 |
public function handle_error() {
|
441 |
$this->send_response( new WP_Error( 'unhandled_request', 'This request was not handled by any registered verb. This was likely caused by a fatal error.' ) );
|
442 |
}
|
@@ -463,6 +479,29 @@ class Ithemes_Sync_Request_Handler {
|
|
463 |
|
464 |
return $json;
|
465 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
466 |
}
|
467 |
|
468 |
new Ithemes_Sync_Request_Handler();
|
35 |
|
36 |
|
37 |
require_once( $GLOBALS['ithemes_sync_path'] . '/load-translations.php' );
|
38 |
+
require_once( $GLOBALS['ithemes_sync_path'] . '/functions.php' );
|
39 |
|
40 |
class Ithemes_Sync_Request_Handler {
|
41 |
private $logs = array();
|
46 |
|
47 |
public function __construct() {
|
48 |
$this->show_errors();
|
49 |
+
|
|
|
50 |
if ( empty( $_POST['request'] ) ) {
|
51 |
return;
|
52 |
}
|
53 |
+
|
54 |
+
require_once( $GLOBALS['ithemes_sync_path'] . '/api.php' );
|
55 |
+
require_once( $GLOBALS['ithemes_sync_path'] . '/functions.php' );
|
56 |
+
require_once( $GLOBALS['ithemes_sync_path'] . '/settings.php' );
|
57 |
+
|
58 |
+
add_action( 'ithemes-sync-add-log', array( $this, 'add_log' ), 10, 2 );
|
59 |
+
add_action( 'shutdown', array( $this, 'handle_error' ) );
|
60 |
+
add_action( 'ithemes_sync_verbs_registered', array( $this, 'handle_request' ) );
|
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 |
}
|
89 |
if ( ! is_array( $request ) ) {
|
90 |
return;
|
91 |
}
|
92 |
+
|
|
|
93 |
$GLOBALS['ithemes_sync_request_handler'] = $this;
|
94 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
$this->options = $GLOBALS['ithemes-sync-settings']->get_options();
|
96 |
|
97 |
$this->parse_request( $request );
|
293 |
|
294 |
public function send_response( $data ) {
|
295 |
if ( is_wp_error( $data ) ) {
|
296 |
+
foreach ( $data->get_error_codes() as $code ) {
|
297 |
+
$response['errors'][ $code ] = $data->get_error_message( $code );
|
298 |
+
}
|
299 |
+
} else {
|
300 |
$response = array(
|
301 |
'response' => $data,
|
302 |
);
|
303 |
}
|
304 |
+
|
305 |
if ( ! empty( $this->logs ) ) {
|
306 |
$response['logs'] = $this->logs;
|
307 |
}
|
452 |
|
453 |
$this->logs[] = $log;
|
454 |
}
|
455 |
+
|
456 |
public function handle_error() {
|
457 |
$this->send_response( new WP_Error( 'unhandled_request', 'This request was not handled by any registered verb. This was likely caused by a fatal error.' ) );
|
458 |
}
|
479 |
|
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 |
+
try {
|
494 |
+
|
495 |
+
$public_key = sodium_base642bin( file_get_contents( $GLOBALS['ithemes_sync_path'] . '/public.key' ), 5 );
|
496 |
+
$signature = sodium_base642bin( $signature, 5 );
|
497 |
+
|
498 |
+
} catch ( Exception $e ) {
|
499 |
+
return false;
|
500 |
+
}
|
501 |
+
|
502 |
+
return sodium_crypto_sign_verify_detached( $signature, $request, $public_key );
|
503 |
+
}
|
504 |
+
|
505 |
}
|
506 |
|
507 |
new Ithemes_Sync_Request_Handler();
|