File: /home/zwafgyp/dodolodge-net/wp-content/plugins/wp-malware-removal/traits/wpmr_checksums.php
<?php
/**
* WPMR_Checksums_Trait
*
* Generated during Phase 2 restructuring
* This trait contains methods extracted from the original monolithic wpmr.php
*
* @package WP_Malware_Removal
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
trait WPMR_Checksums {
function fails_checksum( $local_file ) {
if ( $this->is_invalid_file( $local_file ) ) {
if ( $this->is_scannable_file( $local_file ) ) {
return true;
}
return;
}
if ( ! empty( $GLOBALS['WPMR']['regex'] ) ) {
remove_filter( 'serve_checksums', array( $this, 'get_cached_checksums' ), 11 );
}
$hash = @hash_file( 'sha256', $local_file );
// ensure that for files in core wp dir, only the respective checksums are matched.
if ( $this->is_in_core_wp_dir( $local_file ) ) {
$checksums = $GLOBALS['WPMR']['core_checksums'];
} else { // file not in core wp dir
$checksums = $GLOBALS['WPMR']['checksums'];
}
// $checksums = $GLOBALS['WPMR']['checksums']; // testing if file is shown on rescan
// For core files, check if the file path exists in checksums AND hash matches
// For non-core files, just check if hash exists in checksums values
$checksum_failed = false;
if ( $this->is_in_core_wp_dir( $local_file ) ) {
// Core file: must have both the path registered AND matching hash
$relative_path = $this->get_core_relative_path( $local_file );
$checksum_failed = ! isset( $checksums[ $relative_path ] ) || $checksums[ $relative_path ] !== $hash;
} else {
// Non-core file: just check if hash exists in known checksums
$checksum_failed = ! in_array( $hash, $checksums );
}
if ( $checksum_failed || $this->is_file_blacklisted( $hash ) ) {
if ( ! $this->is_registered() ) {
if (
$this->normalise_path( $local_file ) == $this->normalise_path( trailingslashit( ABSPATH ) . 'wp-config.php' ) ||
$this->normalise_path( $local_file ) == $this->normalise_path( trailingslashit( ABSPATH ) . '.htaccess' ) ||
$this->normalise_path( $local_file ) == $this->normalise_path( trailingslashit( WP_CONTENT_DIR ) . 'index.php' ) ||
$this->normalise_path( $local_file ) == $this->normalise_path( trailingslashit( WP_PLUGIN_DIR ) . 'index.php' ) ||
$this->normalise_path( $local_file ) == $this->normalise_path( trailingslashit( get_theme_root() ) . 'index.php' )
) {
// uncommenting the next line could lead to false negatives
// return false; // ignore known files that may not have a checksum at all
}
}
return 'missing';
}
return;
}
function update_cached_checksums( $clean_files ) {
if ( empty( $clean_files ) ) {
return;
}
$checksums = $this->get_checksums();
$new_checksums = array();
foreach ( $clean_files as $file ) {
if ( empty( $checksums[ $file ] ) && ! $this->is_invalid_file( $file ) ) {
$sha256 = @hash_file( 'sha256', $file );
if ( ! empty( $sha256 ) ) {
$new_checksums[ $file ] = $sha256;
}
}
}
$cached_checksums = get_option( 'WPMR_files_checksums_cache' );
if ( $cached_checksums && is_array( $cached_checksums ) && ! empty( $cached_checksums ) ) {
update_option( 'WPMR_files_checksums_cache', array_merge( $cached_checksums, $new_checksums ) );
} else {
update_option( 'WPMR_files_checksums_cache', $new_checksums );
}
}
function get_checksums_values() {
$checksums = $this->get_checksums();
$checksum_values = array_values( $checksums );
$checksum_values = array_unique( $checksum_values, SORT_REGULAR );
return $checksum_values;
}
function get_cached_checksums( $checksums ) {
if ( ! empty( $GLOBALS['WPMR']['debug'] ) ) { // This element doesn't exist on page load, only exists on ajax requests
return $checksums;
}
$cached_checksums = get_option( 'WPMR_files_checksums_cache' );
if ( $cached_checksums && is_array( $cached_checksums ) && ! empty( $cached_checksums ) ) {
return array_merge( $checksums, $cached_checksums );
}
return $checksums;
}
function delete_generated_checksums() {
delete_option( 'WPMR_files_checksums_cache' );
delete_option( 'WPMR_db_checksums_cache' );
}
function delete_core_checksums( $upgrader, $hook_extra ) {
$this->flog( '$upgrader' );
$this->flog( $upgrader );
$this->flog( '$hook_extra' );
$this->flog( $hook_extra );
delete_option( 'WPMR_checksums' );
}
function get_checksums( $cached = true ) {
$this->raise_limits_conditionally();
$checksums = get_option( 'WPMR_checksums' );
if ( get_transient( 'wpmr_checksum_fetch_lock' ) ) {
$checksums = $checksums ? $checksums : array();
return apply_filters( 'serve_checksums', $checksums );
}
if ( ! $checksums || ! $cached ) {
$manifest = $this->build_checksums_manifest();
if ( empty( $manifest ) ) {
return array();
}
$request = $this->saas_request(
'saas_get_checksums',
array(
'method' => 'POST',
'send_state' => 'body',
'body' => array(
'components' => wp_json_encode( $manifest ),
),
'timeout' => max( 60, (int) $this->timeout ),
)
);
if ( is_wp_error( $request ) ) {
$this->flog( 'Checksum batch request failed: ' . $request->get_error_message() );
set_transient( 'wpmr_checksum_fetch_lock', true, MINUTE_IN_SECONDS );
return array();
}
$payload = null;
if ( isset( $request['payload'] ) && is_array( $request['payload'] ) ) {
$payload = $request['payload'];
}
$checksums = $this->flatten_checksum_payload( $payload );
if ( ! empty( $checksums ) ) {
update_option( 'WPMR_checksums', $checksums );
delete_transient( 'wpmr_checksum_fetch_lock' );
}
else {
set_transient( 'wpmr_checksum_fetch_lock', true, MINUTE_IN_SECONDS );
}
}
return apply_filters( 'serve_checksums', $checksums );
}
function build_checksums_manifest() {
global $wp_version;
$locale = $this->get_locale();
if ( empty( $locale ) ) {
$locale = get_locale();
}
if ( empty( $locale ) ) {
$locale = 'en_US';
}
$manifest = array(
'core' => array(
'slug' => 'wordpress',
'version' => $wp_version,
'locale' => $locale,
),
'plugins' => array(),
'themes' => array(),
);
$install_path = trailingslashit( wp_normalize_path( ABSPATH ) );
$all_plugins = get_plugins();
foreach ( $all_plugins as $key => $plugin_data ) {
if ( false === strpos( $key, '/' ) ) {
continue;
}
$plugin_file = trailingslashit( dirname( $this->dir ) ) . $key;
$plugin_file = wp_normalize_path( $plugin_file );
$plugin_file = ltrim( str_replace( $install_path, '', $plugin_file ), '/' );
$manifest['plugins'][] = array(
'slug' => dirname( $key ),
'version' => isset( $plugin_data['Version'] ) ? $plugin_data['Version'] : '',
'base_path' => $this->normalise_component_path( dirname( $plugin_file ) ),
);
}
$themes = wp_get_themes();
foreach ( $themes as $slug => $theme ) {
$theme_dir = $theme->get_stylesheet_directory();
if ( empty( $theme_dir ) ) {
continue;
}
$manifest['themes'][] = array(
'slug' => $slug,
'version' => $theme->get( 'Version' ),
'base_path' => $this->normalise_component_path( $theme_dir ),
);
}
return $manifest;
}
function flatten_checksum_payload( $payload ) {
if ( empty( $payload ) || ! is_array( $payload ) ) {
return array();
}
$flat = array();
if ( ! empty( $payload['core'] ) && ! empty( $payload['core']['files'] ) && is_array( $payload['core']['files'] ) ) {
foreach ( $payload['core']['files'] as $file => $hashes ) {
$hash = $this->extract_checksum_hash( $hashes );
if ( empty( $hash ) ) {
continue;
}
$relative = $this->normalise_component_path( $file );
if ( '' !== $relative ) {
$flat[ $relative ] = $hash;
}
}
}
foreach ( array( 'plugins', 'themes' ) as $section ) {
if ( empty( $payload[ $section ] ) || ! is_array( $payload[ $section ] ) ) {
continue;
}
foreach ( $payload[ $section ] as $component ) {
if ( empty( $component['files'] ) || empty( $component['base_path'] ) ) {
continue;
}
$base_path = $this->normalise_component_path( $component['base_path'] );
if ( '' === $base_path ) {
continue;
}
$base_path = trailingslashit( $base_path );
foreach ( $component['files'] as $file => $hashes ) {
$hash = $this->extract_checksum_hash( $hashes );
if ( empty( $hash ) ) {
continue;
}
$relative = ltrim( $this->normalise_component_path( $file ), '/' );
$flat[ $base_path . $relative ] = $hash;
}
}
}
return $flat;
}
function extract_checksum_hash( $entry ) {
if ( empty( $entry ) ) {
return '';
}
if ( is_array( $entry ) && ! empty( $entry['sha256'] ) ) {
return $entry['sha256'];
}
return '';
}
function normalise_component_path( $path ) {
if ( empty( $path ) ) {
return '';
}
$normalised = wp_normalize_path( $path );
$abspath = trailingslashit( wp_normalize_path( ABSPATH ) );
if ( 0 === strpos( $normalised, $abspath ) ) {
$normalised = substr( $normalised, strlen( $abspath ) );
}
$normalised = ltrim( $normalised, '/' );
$normalised = preg_replace( '#/+#', '/', $normalised );
return untrailingslashit( $normalised );
}
function map_core_checksums( $checksums ) {
$real_abspath = trailingslashit( $this->normalise_path( ABSPATH ) );
foreach ( $checksums as $f => $c ) {
$checksums[ $real_abspath . $f ] = $c;
unset( $checksums[ $f ] );
}
return $checksums;
}
function checksums_delete_invalid() {
$cached_checksums = get_option( 'WPMR_files_checksums_cache' );
if ( ! $cached_checksums || ! is_array( $cached_checksums ) ) {
return;
}
foreach ( $cached_checksums as $file => $checksum ) {
if ( $this->is_invalid_file( $file ) ) {
unset( $cached_checksums[ $file ] );
}
}
update_option( 'WPMR_files_checksums_cache', $cached_checksums );
}
function get_db_checksums() {
return get_option( 'WPMR_db_checksums_cache', array() );
}
}