Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
<?php
|
|
|
|
/**
|
2019-04-16 07:09:51 +02:00
|
|
|
* Error Protection API: WP_Recovery_Mode_Key_Service class
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
*
|
|
|
|
* @package WordPress
|
2020-01-29 01:45:18 +01:00
|
|
|
* @since 5.2.0
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Core class used to generate and validate keys used to enter Recovery Mode.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*/
|
|
|
|
final class WP_Recovery_Mode_Key_Service {
|
|
|
|
|
2019-04-16 07:09:51 +02:00
|
|
|
/**
|
|
|
|
* The option name used to store the keys.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
private $option_name = 'recovery_keys';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a recovery mode token.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
2020-06-20 00:55:12 +02:00
|
|
|
* @return string A random string to identify its associated key in storage.
|
2019-04-16 07:09:51 +02:00
|
|
|
*/
|
|
|
|
public function generate_recovery_mode_token() {
|
|
|
|
return wp_generate_password( 22, false );
|
|
|
|
}
|
|
|
|
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
/**
|
|
|
|
* Creates a recovery mode key.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
|
|
|
* @global PasswordHash $wp_hasher
|
|
|
|
*
|
2019-04-16 07:09:51 +02:00
|
|
|
* @param string $token A token generated by {@see generate_recovery_mode_token()}.
|
2020-06-20 00:55:12 +02:00
|
|
|
* @return string Recovery mode key.
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
*/
|
2019-04-16 07:09:51 +02:00
|
|
|
public function generate_and_store_recovery_mode_key( $token ) {
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
|
|
|
|
global $wp_hasher;
|
|
|
|
|
|
|
|
$key = wp_generate_password( 22, false );
|
|
|
|
|
|
|
|
if ( empty( $wp_hasher ) ) {
|
|
|
|
require_once ABSPATH . WPINC . '/class-phpass.php';
|
|
|
|
$wp_hasher = new PasswordHash( 8, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
$hashed = $wp_hasher->HashPassword( $key );
|
|
|
|
|
2019-04-16 07:09:51 +02:00
|
|
|
$records = $this->get_keys();
|
|
|
|
|
|
|
|
$records[ $token ] = array(
|
|
|
|
'hashed_key' => $hashed,
|
|
|
|
'created_at' => time(),
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
);
|
|
|
|
|
2019-04-16 07:09:51 +02:00
|
|
|
$this->update_keys( $records );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fires when a recovery mode key is generated.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
|
|
|
* @param string $token The recovery data token.
|
|
|
|
* @param string $key The recovery mode key.
|
|
|
|
*/
|
|
|
|
do_action( 'generate_recovery_mode_key', $token, $key );
|
|
|
|
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
return $key;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Verifies if the recovery mode key is correct.
|
|
|
|
*
|
2019-04-16 07:09:51 +02:00
|
|
|
* Recovery mode keys can only be used once; the key will be consumed in the process.
|
|
|
|
*
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
* @since 5.2.0
|
|
|
|
*
|
2019-04-16 07:09:51 +02:00
|
|
|
* @param string $token The token used when generating the given key.
|
|
|
|
* @param string $key The unhashed key.
|
|
|
|
* @param int $ttl Time in seconds for the key to be valid for.
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
* @return true|WP_Error True on success, error object on failure.
|
|
|
|
*/
|
2019-04-16 07:09:51 +02:00
|
|
|
public function validate_recovery_mode_key( $token, $key, $ttl ) {
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
|
2019-04-16 07:09:51 +02:00
|
|
|
$records = $this->get_keys();
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
|
2019-04-16 07:09:51 +02:00
|
|
|
if ( ! isset( $records[ $token ] ) ) {
|
|
|
|
return new WP_Error( 'token_not_found', __( 'Recovery Mode not initialized.' ) );
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
}
|
|
|
|
|
2019-04-16 07:09:51 +02:00
|
|
|
$record = $records[ $token ];
|
|
|
|
|
|
|
|
$this->remove_key( $token );
|
|
|
|
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
if ( ! is_array( $record ) || ! isset( $record['hashed_key'], $record['created_at'] ) ) {
|
|
|
|
return new WP_Error( 'invalid_recovery_key_format', __( 'Invalid recovery key format.' ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! wp_check_password( $key, $record['hashed_key'] ) ) {
|
|
|
|
return new WP_Error( 'hash_mismatch', __( 'Invalid recovery key.' ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( time() > $record['created_at'] + $ttl ) {
|
|
|
|
return new WP_Error( 'key_expired', __( 'Recovery key expired.' ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2019-04-16 07:09:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes expired recovery mode keys.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
|
|
|
* @param int $ttl Time in seconds for the keys to be valid for.
|
|
|
|
*/
|
|
|
|
public function clean_expired_keys( $ttl ) {
|
|
|
|
|
|
|
|
$records = $this->get_keys();
|
|
|
|
|
|
|
|
foreach ( $records as $key => $record ) {
|
|
|
|
if ( ! isset( $record['created_at'] ) || time() > $record['created_at'] + $ttl ) {
|
|
|
|
unset( $records[ $key ] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->update_keys( $records );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes a used recovery key.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
|
|
|
* @param string $token The token used when generating a recovery mode key.
|
|
|
|
*/
|
|
|
|
private function remove_key( $token ) {
|
|
|
|
|
|
|
|
$records = $this->get_keys();
|
|
|
|
|
|
|
|
if ( ! isset( $records[ $token ] ) ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
unset( $records[ $token ] );
|
|
|
|
|
|
|
|
$this->update_keys( $records );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the recovery key records.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
|
|
|
* @return array Associative array of $token => $data pairs, where $data has keys 'hashed_key'
|
|
|
|
* and 'created_at'.
|
|
|
|
*/
|
|
|
|
private function get_keys() {
|
|
|
|
return (array) get_option( $this->option_name, array() );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the recovery key records.
|
|
|
|
*
|
|
|
|
* @since 5.2.0
|
|
|
|
*
|
|
|
|
* @param array $keys Associative array of $token => $data pairs, where $data has keys 'hashed_key'
|
|
|
|
* and 'created_at'.
|
|
|
|
* @return bool True on success, false on failure.
|
|
|
|
*/
|
|
|
|
private function update_keys( array $keys ) {
|
|
|
|
return update_option( $this->option_name, $keys );
|
|
|
|
}
|
Bootstrap/Load: Introduce a recovery mode for fixing fatal errors.
Using the new fatal handler introduced in [44962], an email is sent to the admin when a fatal error occurs. This email includes a secret link to enter recovery mode. When clicked, the link will be validated and on success a cookie will be placed on the client, enabling recovery mode for that user. This functionality is executed early before plugins and themes are loaded, in order to be unaffected by potential fatal errors these might be causing.
When in recovery mode, broken plugins and themes will be paused for that client, so that they are able to access the admin backend despite of these errors. They are notified about the broken extensions and the errors caused, and can then decide whether they would like to temporarily deactivate the extension or fix the problem and resume the extension.
A link in the admin bar allows the client to exit recovery mode.
Props timothyblynjacobs, afragen, flixos90, nerrad, miss_jwo, schlessera, spacedmonkey, swissspidy.
Fixes #46130, #44458.
Built from https://develop.svn.wordpress.org/trunk@44973
git-svn-id: http://core.svn.wordpress.org/trunk@44804 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2019-03-21 22:53:51 +01:00
|
|
|
}
|