Файловый менеджер - Редактировать - /home/bean7936/perfect-community.com/wp-content/plugins/secupress/free/functions/files.php
Назад
<?php defined( 'ABSPATH' ) or die( 'Something went wrong.' ); /** * Get WP Direct filesystem object. * * @since 1.3 Don't use the global Filesystem anymore, to make sure to use "direct" (some things don't work over "ftp"). * @since 1.0 * @author Grégory Viguier * * @return `$wp_filesystem` object. */ function secupress_get_filesystem() { static $filesystem; if ( $filesystem ) { return $filesystem; } require_once( ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php' ); require_once( ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php' ); $filesystem = new WP_Filesystem_Direct( new StdClass() ); // WPCS: override ok. // Set the permission constants if not already set. if ( ! defined( 'FS_CHMOD_DIR' ) ) { define( 'FS_CHMOD_DIR', ( @fileperms( ABSPATH ) & 0777 | 0755 ) ); } if ( ! defined( 'FS_CHMOD_FILE' ) ) { define( 'FS_CHMOD_FILE', ( @fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 ) ); } return $filesystem; } /** * Remove a single file or a folder recursively. * * @since 1.0 * @author Grégory Viguier * * @param (string) $dir File/Directory to delete. * @param (array) $dirs_to_preserve Dirs that should not be deleted. Default: array(). */ function secupress_rrmdir( $dir, $dirs_to_preserve = array() ) { $dir = rtrim( $dir, '/' ); /** * Fires after a file/directory cache was deleted. * * @since 1.0 * * @param (string) $dir File/Directory to delete. * @param (array) $dirs_to_preserve Directories that should not be deleted. */ do_action( 'secupress.before_rrmdir', $dir, $dirs_to_preserve ); $filesystem = secupress_get_filesystem(); if ( ! $filesystem->is_dir( $dir ) ) { $filesystem->delete( $dir ); return; }; if ( $dirs = glob( $dir . '/*', GLOB_NOSORT ) ) { $keys = array(); foreach ( $dirs_to_preserve as $dir_to_preserve ) { $matches = preg_grep( "#^$dir_to_preserve$#" , $dirs ); $keys[] = reset( $matches ); } $dirs = array_diff( $dirs, array_filter( $keys ) ); foreach ( $dirs as $dir ) { if ( $filesystem->is_dir( $dir ) ) { secupress_rrmdir( $dir, $dirs_to_preserve ); } else { $filesystem->delete( $dir ); } } } $filesystem->delete( $dir ); /** * Fires before a file/directory cache was deleted. * * @since 1.0 * * @param (string) $dir File/Directory to delete. * @param (array) $dirs_to_preserve Dirs that should not be deleted. */ do_action( 'secupress.after_rrmdir', $dir, $dirs_to_preserve ); } /** * Directory creation based on WordPress Filesystem. * * @since 1.0 * * @param (string) $dir The path of directory will be created. * * @return (bool) */ function secupress_mkdir( $dir ) { $filesystem = secupress_get_filesystem(); return $filesystem->mkdir( $dir ); } /** * Recursive directory creation based on full path. * * @since 1.0 * @author Grégory Viguier * * @see wp_mkdir_p() in `/wp-includes/functions.php`. * * @param (string) $target A folder path. * * @return True on success. */ function secupress_mkdir_p( $target ) { $target = wp_normalize_path( $target ); $filesystem = secupress_get_filesystem(); // Safe mode fails with a trailing slash under certain PHP versions. $target = rtrim( $target, '/' ); if ( empty( $target ) ) { $target = '/'; } if ( $filesystem->exists( $target ) ) { return $filesystem->is_dir( $target ); } // Attempting to create the directory may clutter up our display. if ( $filesystem->mkdir( $target ) ) { return true; } elseif ( $filesystem->is_dir( dirname( $target ) ) ) { return false; } // If the above failed, attempt to create the parent node, then try again. if ( '/' !== $target && secupress_mkdir_p( dirname( $target ) ) ) { return secupress_mkdir_p( $target ); } return false; } /** * Tell if a file located in the home folder is writable. * If the file does not exist, tell if the home folder is writable. * * @since 1.0 * @author Grégory Viguier * * @param (string) $file File name. * * @return (bool) */ function secupress_root_file_is_writable( $file ) { static $home_path; if ( ! isset( $home_path ) ) { $home_path = secupress_get_home_path(); } return wp_is_writable( $home_path . $file ) || ! file_exists( $home_path . $file ) && wp_is_writable( $home_path ); } /** * Try to find the correct `wp-config.php` file, support one level up in filetree. * * @since 2.0 Add filter secupress.wpconfig_path to target another file with your constants * @author Julio Potier * @since 1.0 * @author Grégory Viguier * * @hook secupress.wpconfig_filename * @param (string) $context Can be use for filtering * @return (string|bool) The path of `wp-config.php` file or false. */ function secupress_find_wpconfig_path( $context = '' ) { $config_file = ABSPATH . 'wp-config.php'; $config_file_alt = dirname( ABSPATH ) . '/wp-config.php'; if ( file_exists( $config_file ) ) { /** * Filter the wp-config.php file path * * @param (string) The default file path for wp-config.php * @since 2.0 * @author Julio Potier */ return apply_filters( 'secupress.wpconfig_path', $config_file, 'main', $context ); } if ( @file_exists( $config_file_alt ) && ! file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) { /** * Filter the wp-config.php file path * * @param (string) The default file path for wp-config.php * @since 2.0 * @author Julio Potier */ return apply_filters( 'secupress.wpconfig_path', $config_file_alt, 'alt', $context ); } // No writable file found. return false; } /** * Allow interface to display a custom filename for wp-config.php * * @since 2.0 * @author Julio Potier * * @see secupress_find_wpconfig_path() * * @hook secupress.wpconfig_filename * @return (string) The custom wpconfig.php **/ function secupress_get_wpconfig_filename( $context = 'filename' ) { $filename = str_replace( ABSPATH, '', secupress_find_wpconfig_path( $context ) ); /** * Filter the wp-config.php filename (custom or not) * * @param (string) The default filename from the real file path * @since 2.0 * @author Julio Potier */ return apply_filters( 'secupress.wpconfig_filename', $filename, $context ); } /** * Tell if the `wp-config.php` file is writable. * * @since 1.2.4 Return null if the file can't be located. * @since 1.2.2 * @author Grégory Viguier * * @return (string|bool|null) The path of `wp-config.php` file if writable, false if not writable, null if the file doesn't exist. */ function secupress_is_wpconfig_writable( $context = '' ) { $wpconfig_filepath = secupress_find_wpconfig_path( $context ); if ( ! $wpconfig_filepath ) { return null; } return wp_is_writable( $wpconfig_filepath ) ? $wpconfig_filepath : false; } /** * Check if a given muplugin is present in mu-plugins/ folder * * @since 2.3.7 * @author Julio Potier * * @param (string) $filename_part * * @return (bool) **/ function secupress_muplugin_exists( $filename_part ) { static $filename_parts; if ( ! file_exists( WPMU_PLUGIN_DIR ) ) { return false; } if ( ! isset( $filename_parts ) ) { $filename_parts = []; } $found_files = glob( WPMU_PLUGIN_DIR . "/{_secupress_{$filename_part}*,(secupress_{$filename_part}*}.php", GLOB_BRACE ); $filename_parts[ $filename_part ] = ! empty( $found_files ); return $filename_parts[ $filename_part ]; } /** * Check if a given marker is present in wpconfig file * * @since 2.3.7 * @author Julio Potier * * @param (string) $marker * * @return (bool) **/ function secupress_marker_exists_in_wpconfig( $marker ) { static $file_content = ''; $wpconfig_filepath = secupress_is_wpconfig_writable(); if ( ! $wpconfig_filepath ) { return false; } $filesystem = secupress_get_filesystem(); if ( ! $file_content ) { $file_content = $filesystem->get_contents( $wpconfig_filepath ); } return preg_match( "@[\t ]*?# BEGIN SecuPress {$marker}\s.*# END SecuPress\s*?@sU", $file_content ); } /** * Comment a constant definition in the `wp-config.php` file (or any other file). * If `$marker` is provided, our definition will be also removed. * * @since 2.0 Change the return values to let a possible TRUE if these are WP defaults + remove $new_value param (unused and not the purpose) * @author Julio Potier * @since 1.2.2 * @author Grégory Viguier * * @param (string) $constant Name of the constant. * @param (string) $wpconfig_filepath Path to the `wp-config.php` file. * @param (string) $marker Name of the marker used to define the constant ourself. * * @return (bool) */ function secupress_comment_constant( $constant, $wpconfig_filepath = false, $marker = false ) { static $file_content = ''; if ( ! $wpconfig_filepath ) { $wpconfig_filepath = secupress_is_wpconfig_writable(); if ( ! $wpconfig_filepath ) { return false; } } $filesystem = secupress_get_filesystem(); if ( ! $file_content ) { $file_content = $filesystem->get_contents( $wpconfig_filepath ); } if ( $marker && preg_match( "@[\t ]*?# BEGIN SecuPress {$marker}\s.*# END SecuPress\s*?@sU", $file_content ) ) { // Remove the constant we could have previously set. return secupress_replace_content( $wpconfig_filepath, "@[\t ]*?# BEGIN SecuPress {$marker}\s.*# END SecuPress\s*?@sU", '' ); } // Comment old value. if ( preg_match( "@^[\t ]*define\s*\(\s*(?:'{$constant}'|\"{$constant}\")\s*,(?:.*);.*\s*$@mU", $file_content ) ) { return secupress_replace_content( $wpconfig_filepath, "@^[\t ]*define\s*\(\s*(?:'{$constant}'|\"{$constant}\")\s*,(?:.*);.*\s*$@mU", '/** Commented by SecuPress. */ /** $0 */' ); } // Nothing has been replaced because there is nothing to replace, aka, these are WordPress default values, still overridable // ps: if these constants are set elsewhere… well, my bad :) return true; } /** * Uncomment a constant definition in the `wp-config.php` file (or any other file). * If `$marker` is provided, our definition will be also removed. * * @since 1.2.2 * @author Grégory Viguier * * @param (string) $constant Name of the constant. * @param (string) $wpconfig_filepath Path to the `wp-config.php` file. * @param (string) $marker Name of the marker used to define the constant ourself. * * @return (bool) True if the constant definition has been successfully uncommented. False if: * - the constant is already defined somewhere, * - or the file is not writable, * - or the comment was not found in the file, * - or it couldn't be uncommented. * So basically, this information is totally useless, deal with it. */ function secupress_uncomment_constant( $constant, $wpconfig_filepath = false, $marker = false ) { if ( ! $wpconfig_filepath ) { $wpconfig_filepath = secupress_is_wpconfig_writable(); if ( ! $wpconfig_filepath ) { return false; } } if ( $marker ) { // Remove the constant we could have previously set. $replaced = secupress_replace_content( $wpconfig_filepath, "@[\t ]*?# BEGIN SecuPress {$marker}\s.*# END SecuPress\s*?@sU", '' ); if ( defined( $constant ) && ! $replaced ) { /** * If the constant is defined and "our" has not been removed (because it didn't exist), that means it's defined somewhere else. * In that case, we must not uncomment the previous value or it will be defined twice. */ return false; } } // Uncomment old value. $constant = "(define\s*\(\s*(?:'$constant'|\"$constant\")\s*,(?:.*))"; $p = "@^[\t ]*/\*+\s*Commented by SecuPress\.*\s*\*/\s*?(?:/\*+\s*{$constant}\s*\*/|/+\s*{$constant})\s*$@mU"; return secupress_replace_content( $wpconfig_filepath, $p, '$1' ); } /** * Get plugins dir path. * * @since 1.0 * @author Grégory Viguier * @return (string) */ function secupress_get_plugins_path() { static $plugins_dir; if ( ! isset( $plugins_dir ) ) { $plugins_dir = realpath( WP_PLUGIN_DIR ) . DIRECTORY_SEPARATOR; } return $plugins_dir; } /** * Get themes dir path. * * @since 1.0 * * @return (string) */ function secupress_get_themes_path() { static $themes_dir; if ( ! isset( $themes_dir ) ) { $wp_filesystem = secupress_get_filesystem(); // WPCS: override ok. $themes_dir = realpath( $wp_filesystem->wp_themes_dir() ) . DIRECTORY_SEPARATOR; } return $themes_dir; } /** * Tell if a plugin is symlinked. * * @since 1.0 * @author Grégory Viguier * * @param (string) $plugin_file Plugin main file path, relative to the plugins folder. * * @return (bool) True if the plugin is symlinked. */ function secupress_is_plugin_symlinked( $plugin_file ) { $plugins_dir = secupress_get_plugins_path(); $plugin_path = realpath( $plugins_dir . $plugin_file ); return ! ( $plugin_path && 0 === strpos( $plugin_path, $plugins_dir ) ); } /** * Tell if a theme is symlinked. * * @since 1.0 * @author Grégory Viguier * * @param (string) $theme_slug Theme dir name. * * @return (bool) True if the theme is symlinked. */ function secupress_is_theme_symlinked( $theme_slug ) { $themes_dir = secupress_get_themes_path(); $theme_path = realpath( $themes_dir . $theme_slug ); return ! ( $theme_path && 0 === strpos( $theme_path, $themes_dir ) ); } /** * File creation based on WordPress Filesystem. * * @since 2.2.6 $file_content is now an array + clearstatcache() usage * @author Julio Potier * @since 1.0 * @author Grégory Viguier * * @param (string) $file The path of file. * @param (string) $new_content The content that will be added to the file. * @param (array) $args (optional) * marker (string): An additional suffix string to add to the "SecuPress" marker, Default ''. * put (string): (prepend|append|replace): Prepend or append content in the file, Default 'prepend'. * text (string): When (prepend|append) is used for "put", you can speficy a text to find, it will be pre/appended around this text. * @return (bool) */ function secupress_put_contents( $file, $new_content = '', $args = array() ) { $args = wp_parse_args( $args, array( 'marker' => '', 'put' => 'prepend', 'text' => '', 'keep_old' => false, ) ); $filesystem = secupress_get_filesystem(); $comment_char = pathinfo( $file, PATHINFO_EXTENSION ) !== 'ini' ? '#' : ';'; // Get the whole content of file and remove old marker content. if ( file_exists( $file ) ) { $pattern = '/' . $comment_char . ' BEGIN SecuPress ' . $args['marker'] . '(.*)' . $comment_char . ' END SecuPress\s*?/isU'; $file_content[ $file ] = file_get_contents( $file ); if ( $args['keep_old'] ) { preg_match( $pattern, $file_content[ $file ], $keep_old ); } $file_content[ $file ] = preg_replace( $pattern, '', $file_content[ $file ] ); } if ( ! empty( $new_content ) ) { $content = $comment_char . ' BEGIN SecuPress ' . $args['marker'] . PHP_EOL; if ( $args['keep_old'] && isset( $keep_old[1] ) ) { $content .= trim( $keep_old[1] ) . "\n"; } $content .= trim( $new_content ) . PHP_EOL; $content .= $comment_char . ' END SecuPress' . PHP_EOL . PHP_EOL; if ( '' !== $args['text'] && strpos( $file_content[ $file ], $args['text'] ) !== false ) { if ( 'append' === $args['put'] ) { $content = str_replace( $args['text'], $args['text'] . PHP_EOL . $content, $file_content[ $file ] ); } elseif ( 'prepend' === $args['put'] ) { $content = str_replace( $args['text'], $content . PHP_EOL . $args['text'], $file_content[ $file ] ); } } else { if ( 'append' === $args['put'] ) { $content = $file_content[ $file ] . PHP_EOL . $content; } elseif ( 'prepend' === $args['put'] ) { $content = $content . $file_content[ $file ]; } } $file_content[ $file ] = $content; } $return = $filesystem->put_contents( $file, $file_content[ $file ], FS_CHMOD_FILE ); clearstatcache( true, $file ); return $return; } /** * File creation based on WordPress Filesystem. * * @since 2.2.6 clearstatcache() usage * @author Julio potier * @since 1.3 Use a sandbox for the `wp-config.php` file. * @since 1.0 * @author Grégory Viguier * * @param (string) $file The path of file will be created. * @param (string) $old_content The content to be replaced from the file (preg_replace). * @param (string) $new_content The new content (preg_replace). * * @return (bool) */ function secupress_replace_content( $file, $old_content, $new_content, $skip_sandbox = false ) { static $file_content = ''; if ( ! file_exists( $file ) ) { return false; } $filesystem = secupress_get_filesystem(); if ( ! $file_content ) { $file_content = $filesystem->get_contents( $file ); } $new_content = preg_replace( $old_content, $new_content, $file_content ); if ( null === $new_content || $new_content === $file_content ) { return false; } $file_content = $new_content; $filename = preg_quote( secupress_get_wpconfig_filename() ); $skip_sandbox = ( ! defined( 'SECUPRESS_NO_SANDBOX' ) || ! SECUPRESS_NO_SANDBOX ) && $skip_sandbox; if ( ! $skip_sandbox && false !== preg_match( '@/$filename$@', $file ) && true !== secupress_wpconfig_success_in_sandbox( $new_content ) ) { return false; } $return = $filesystem->put_contents( $file, $new_content, FS_CHMOD_FILE ); clearstatcache( true, $file ); return $return; } /** * A sandbox for doing crazy things with `wp-config.php`. * Create a folder containing a `index.php` file with the provided content. * Then, make a request to the `index.php` file to test if a server error is triggered. * * @author Julio Potier * @since 2.0 Add secupress.use_sandbox filter * * @author Grégory Viguier * @since 1.3 * * @param (string) $content The content to put in the `wp-config.php` file. * * @return (object|bool) Return true if the server does not trigger an error 500, false otherwise. * Return a WP_Error object if the sandbox creation fails or if the HTTP request fails. */ function secupress_wpconfig_success_in_sandbox( $content ) { /** * Allows to bypass the sandbox * @since 2.0 * @param (bool) true by default, false to use it. * @param (string) A context. */ if ( false === apply_filters( 'secupress.use_sandbox', true, 'wp-config' ) ) { return true; } $wp_filesystem = secupress_get_filesystem(); $file_name = 'index.php'; $folder_name = 'secupress-sandbox-' . uniqid(); $folder_path = ABSPATH . $folder_name; // Remove any `require_once()` and friends. $content = preg_replace( '@(require|include)(_once)?[\s(][^;]+;@', '$foo = "foo";', $content ); // Define `ABSPATH` and add `error_reporting()`. $content = preg_replace( '@^<\?php@', '<?php error_reporting( -1 );', trim( $content ) ); // Print a placeholder when the file is requested. $content .= "\necho 'SANDBOX OK';"; // Create folder. if ( ! $wp_filesystem->mkdir( $folder_path ) ) { return new WP_Error( 'dir_creation_failed', __( 'The temporary directory could not be created.', 'secupress' ) ); } // Create `index.php` file with our content. if ( ! $wp_filesystem->put_contents( $folder_path . '/' . $file_name, $content, FS_CHMOD_FILE ) ) { $wp_filesystem->delete( $folder_path, true ); return new WP_Error( 'file_creation_failed', __( 'The temporary file could not be created.', 'secupress' ) ); } /** This filter is documented in inc/classes/scanners/class-secupress-scan.php. */ $timeout = apply_filters( 'secupress.remote_timeout', 30 ); $origin = 'wp-config-sandbox'; $request_args = array( 'redirection' => 0, 'timeout' => $timeout, 'local' => true, 'sslverify' => false, 'user-agent' => SECUPRESS_PLUGIN_NAME . '/' . SECUPRESS_VERSION, 'cookies' => $_COOKIE, 'headers' => array( 'X-SecuPress-Origin' => $origin, ), ); /** This filter is documented in inc/classes/scanners/class-secupress-scan.php. */ $request_args = apply_filters( 'secupress.scan.default_request_args', $request_args, $origin ); // Try to reach `index.php`. $request_url = $folder_name . '/' . $file_name . '?' . md5( $folder_name . 's' ) . '=' . md5( $folder_name . 'p' ); $response = wp_remote_get( site_url( $request_url ), $request_args ); // Now we can get rid of the files. $wp_filesystem->delete( $folder_path, true ); // HTTP requests are probably blocked. if ( is_wp_error( $response ) ) { return $response; } // Finally, the answer we were looking for. return 500 !== wp_remote_retrieve_response_code( $response ) && false !== strpos( wp_remote_retrieve_body( $response ), 'SANDBOX OK' ); } /** * From WP Core `async_upgrade()` but using `Automatic_Upgrader_Skin` instead of `Language_Pack_Upgrader_Skin` to have a silent upgrade. * * @since 1.0 * @author Grégory Viguier * * @return (void) */ function secupress_async_upgrades() { // Nothing to do? $language_updates = wp_get_translation_updates(); if ( ! $language_updates ) { return; } // Avoid messing with VCS installs, at least for now. // Noted: this is not the ideal way to accomplish this. $check_vcs = new WP_Automatic_Updater; if ( $check_vcs->is_vcs_checkout( WP_CONTENT_DIR ) ) { return; } foreach ( $language_updates as $key => $language_update ) { $update = ! empty( $language_update->autoupdate ); /** This filter is documented in wp-admin/includes/class-wp-upgrader.php */ $update = apply_filters( 'async_update_translation', $update, $language_update ); if ( ! $update ) { unset( $language_updates[ $key ] ); } } if ( empty( $language_updates ) ) { return; } $skin = new Automatic_Upgrader_Skin(); $lp_upgrader = new Language_Pack_Upgrader( $skin ); $lp_upgrader->bulk_upgrade( $language_updates ); } /** * Return all possible matches for a muplugin filename * * @since 2.3.16 $prefix param + basename usage * @since 2.0 * @author Julio Potier * * @param (string) $filename A part of the filename you are looking for * @param (string) $prefix * @return (array) Empty if no file found. **/ function secupress_find_mu_plugin( $filename, $prefix = 'secupress_' ) { $mus = wp_get_mu_plugins(); foreach ( $mus as $i => $mu ) { if ( false === strpos( basename( $mu ), $prefix . $filename ) ) { unset( $mus[ $i ] ); } } return array_values( $mus ); } /** * Creates a MU-PLUGIN. * * @since 2.3.16 3rd param $suffix * @since 2.2.6 New filename pattern * @author Julio Potier * @since 1.0 * @author Grégory Viguier * * @param (string) $filename_part The file name part in `(secupress_{$filename_part}).php`. * @param (string) $contents The file content. * @param (int) $suffix A filename suffix if needed, do not concat into the filename! Usually a uniqid() * * @return (bool) True on success. */ function secupress_create_mu_plugin( $filename_part, $contents, $suffix = '' ) { $suffix = $suffix ? '_' . $suffix : ''; $filesystem = secupress_get_filesystem(); if ( ! file_exists( WPMU_PLUGIN_DIR ) ) { $filesystem->mkdir( WPMU_PLUGIN_DIR ); } if ( secupress_find_mu_plugin( $filename_part ) || ! file_exists( WPMU_PLUGIN_DIR ) ) { return false; } // Delete all previous files $filenames = [ WPMU_PLUGIN_DIR . "/_secupress_{$filename_part}", WPMU_PLUGIN_DIR . "/(secupress_{$filename_part}", // The good one since 2.3 ]; foreach( $filenames as $filename ) { $files = secupress_find_mu_plugin( $filename_part ); if ( $files ) { array_map( 'secupress_delete_mu_plugin', $files ); } } $filename = WPMU_PLUGIN_DIR . "/(secupress_{$filename_part}{$suffix}).php"; $done = $filesystem->put_contents( $filename, $contents ); if ( defined( 'SECUPRESS_INSTALLED_MUPLUGINS' ) ) { $mus = get_option( SECUPRESS_INSTALLED_MUPLUGINS, [] ); if ( $done && $mus ) { $mus[ basename( $filename ) ] = get_plugin_data( $filename ); update_option( SECUPRESS_INSTALLED_MUPLUGINS, $mus ); } } return $done; } /** * Creates a DROPIN-PLUGIN. * * @since 2.2.6 * @author Julio Potier * * @param (string) $filename_part The file name part in `(secupress_{$filename_part}).php`. * @param (string) $contents The file content. * * @return (bool) True on success. */ function secupress_create_dropin_plugin( $filename, $contents ) { $filesystem = secupress_get_filesystem(); $filename = WP_CONTENT_DIR . "/{$filename}.php"; if ( file_exists( $filename ) ) { $filesystem->delete( $filename ); } if ( ! file_exists( WP_CONTENT_DIR ) ) { $filesystem->mkdir( WP_CONTENT_DIR ); } if ( file_exists( $filename ) || ! file_exists( WP_CONTENT_DIR ) ) { return false; } $filesystem->put_contents( $filename, $contents ); } /** * Delete a MU-PLUGIN. * * @since 2.2.6 * @author Julio Potier * * @param (string) $filename The filename or file part in `(secupress_{$filename}).php`. * * @return (bool) True on success. */ function secupress_delete_mu_plugin( $filename ) { if ( ! $filename ) { return false; } $filesystem = secupress_get_filesystem(); $filename = basename( $filename ); $filename = str_replace( [ WPMU_PLUGIN_DIR, '_secupress-', '_secupress_', '(secupress_', ').php', '.php' ], '', $filename ); $oldfile = WPMU_PLUGIN_DIR . "/_secupress-{$filename}.php"; if ( file_exists( $oldfile ) ) { $filesystem->delete( $oldfile ); } $oldfile = WPMU_PLUGIN_DIR . "/_secupress_{$filename}.php"; if ( file_exists( $oldfile ) ) { $filesystem->delete( $oldfile ); } $filename = str_replace( '-', '_', $filename ); $filename = WPMU_PLUGIN_DIR . "/(secupress_{$filename}).php"; if ( file_exists( $filename ) ) { $deleted = $filesystem->delete( $filename ); } if ( ! defined( 'SECUPRESS_INSTALLED_MUPLUGINS' ) ) { return; } $mus = get_option( SECUPRESS_INSTALLED_MUPLUGINS, [] ); if ( empty( $mus ) ) { return false; } unset( $mus[ basename( $filename ) ] ); update_option( SECUPRESS_INSTALLED_MUPLUGINS, $mus ); return $deleted; } /** * Deletes a DROPIN-PLUGIN. * * @since 2.2.6 * @author Julio Potier * * @param (string) $filename The filename or file part in `(secupress_{$filename}).php`. * * @return (bool) True on success. */ function secupress_delete_dropin_plugin( $filename ) { $filesystem = secupress_get_filesystem(); $filename = WP_CONTENT_DIR . "/{$filename}.php"; $dropins = _get_dropins(); if ( isset( $dropins[ basename( $filename ) ] ) && file_exists( $filename ) ) { $filesystem->delete( $filename ); } } /** * Checks the mu-plugins directory and retrieve all mu-plugin files with any plugin data. * * WordPress only includes mu-plugin files in the base mu-plugins directory (wp-content/mu-plugins). * * @since 2.3.17 * @return array[] Array of arrays of mu-plugin data, keyed by plugin file name. See get_plugin_data(). */ function secupress_get_mu_plugins() { $wp_plugins = array(); $plugin_files = array(); if ( ! is_dir( WPMU_PLUGIN_DIR ) ) { return $wp_plugins; } // Files in wp-content/mu-plugins directory. $plugins_dir = @opendir( WPMU_PLUGIN_DIR ); if ( $plugins_dir ) { while ( ( $file = readdir( $plugins_dir ) ) !== false ) { if ( str_ends_with( $file, '.php' ) ) { $plugin_files[] = $file; } } } else { return $wp_plugins; } closedir( $plugins_dir ); if ( empty( $plugin_files ) ) { return $wp_plugins; } foreach ( $plugin_files as $plugin_file ) { if ( ! is_readable( WPMU_PLUGIN_DIR . "/$plugin_file" ) ) { continue; } // Do not apply markup/translate as it will be cached. $plugin_data = get_plugin_data( WPMU_PLUGIN_DIR . "/$plugin_file", false, false ); if ( empty( $plugin_data['Name'] ) ) { $plugin_data['Name'] = $plugin_file; } $wp_plugins[ $plugin_file ] = $plugin_data; } /* REMOVE THIS F NONSENSE if ( isset( $wp_plugins['index.php'] ) && filesize( WPMU_PLUGIN_DIR . '/index.php' ) <= 30 ) { // Silence is golden. unset( $wp_plugins['index.php'] ); } */ // We dont need that here, perf. // uasort( $wp_plugins, '_sort_uname_callback' ); return $wp_plugins; } /** * Format a path with no heading slash and a trailing slash. * If the path is empty, it returns an empty string, not a lonely slash. * Example: foo/bar/ * * @since 1.0 * @author Grégory Viguier * * @param (string) $slug A path. * * @return (string) The path with no heading slash and a trailing slash. */ function secupress_trailingslash_only( $slug ) { return ! is_null( $slug ) ? ltrim( trim( $slug, '/' ) . '/', '/' ) : ''; } /** * A better `get_home_path()`, without the bugs on old versions. * @see https://core.trac.wordpress.org/ticket/25767 * * @since 1.0 * @author Grégory Viguier * * @return (string) The home path. */ function secupress_get_home_path() { $home = set_url_scheme( get_option( 'home' ), 'http' ); $siteurl = set_url_scheme( get_option( 'siteurl' ), 'http' ); if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) { $wp_path_rel_to_home = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */ $pos = strripos( str_replace( '\\', '/', $_SERVER['SCRIPT_FILENAME'] ), trailingslashit( $wp_path_rel_to_home ) ); $home_path = substr( $_SERVER['SCRIPT_FILENAME'], 0, $pos ); $home_path = trailingslashit( $home_path ); } else { $home_path = ABSPATH; } return wp_normalize_path( $home_path ); } /** * Is WP a MultiSite and a subfolder install? * * @since 1.0 * @author Grégory Viguier * * @return (bool). */ function secupress_is_subfolder_install() { global $wpdb; static $subfolder_install; if ( ! isset( $subfolder_install ) ) { if ( is_multisite() ) { $subfolder_install = ! is_subdomain_install(); } elseif ( ! is_null( $wpdb->sitemeta ) ) { $subfolder_install = ! $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" ); } else { $subfolder_install = false; } } return $subfolder_install; } /** * Has WP its own directory? * * @since 1.0 * @author Grégory Viguier * * @see http://codex.wordpress.org/Giving_WordPress_Its_Own_Directory * * @return (string) The directory containing WP. */ function secupress_get_wp_directory() { static $wp_siteurl_subdir; if ( isset( $wp_siteurl_subdir ) ) { return $wp_siteurl_subdir; } $wp_siteurl_subdir = ''; $home = set_url_scheme( rtrim( get_option( 'home' ), '/' ), 'http' ); $siteurl = set_url_scheme( rtrim( get_option( 'siteurl' ), '/' ), 'http' ); if ( ! empty( $home ) && 0 !== strcasecmp( $home, $siteurl ) ) { $wp_siteurl_subdir = str_ireplace( $home, '', $siteurl ); /* $siteurl - $home */ $wp_siteurl_subdir = secupress_trailingslash_only( $wp_siteurl_subdir ); } else { $parsed_url_path = parse_url( $home, PHP_URL_PATH ); if ( '/' !== $parsed_url_path ) { $wp_siteurl_subdir = secupress_trailingslash_only( $parsed_url_path ); } } /** * Filter the returned guessed wp sudbir * * @since 2.4 * @author Julio Potier * * @param (string) $wp_siteurl_subdir * @param (string) $home * @param (string) $siteurl * * @return (string) **/ $wp_siteurl_subdir = apply_filters( 'secupress.get_wp_directory', $wp_siteurl_subdir, $home, $siteurl ); return $wp_siteurl_subdir; } /** * Get infos for the rewrite rules. * The main concern is about directories. * * @since 1.0 * @author Grégory Viguier * * @return (array) An array containing the following keys: * 'base' => Rewrite base, or "home directory". * 'wp_dir' => WP directory. * 'site_dir' => Directory containing the WordPress files. * 'is_sub' => Is it a subfolder install? (Multisite). * 'site_from' => Regex for first part of the rewrite rule (WP files). * 'site_to' => First part of the rewrited address (WP files). * In case of MultiSite with sub-folders, this is not really where the files are: WP rewrites the admin URL for example, which is based on the "site URL". * 'home_from' => Regex for first part of the rewrite rule (home URL). * 'home_to' => First part of the rewrited address (home URL). */ function secupress_get_rewrite_bases() { global $is_apache, $is_nginx, $is_iis7; static $bases; if ( isset( $bases ) ) { return $bases; } $base = wp_parse_url( trailingslashit( get_option( 'home' ) ) ); $base = $base['path']; $wp_dir = secupress_get_wp_directory(); // WP in its own directory. $is_sub = secupress_is_subfolder_install(); // MultiSite by sub-folders. $site_dir = $base . ltrim( $wp_dir, '/' ); $bases = array( 'base' => $base, // '/' or '/sub-dir/'. 'wp_dir' => $wp_dir, // '' or '/wp-dir/'. 'site_dir' => $site_dir, // '/', '/wp-dir/', '/sub-dir/', or '/sub-dir/wp-dir/'. 'is_sub' => $is_sub, // True or false. ); // Apache. if ( $is_apache ) { /** * In the `*_from` fields, we don't add `$base` because we use `RewriteBase $base` in the rewrite rules. * In the `*_to` fields, `$base` is optional, but WP adds it so we do the same for concistancy. */ if ( $is_sub ) { // MultiSite by sub-folders. return ( $bases = array_merge( $bases, array( // 'site_from' and 'site_to': no `$wp_dir` here, because it is used only for the main blog. 'site_from' => $wp_dir ? '([_0-9a-zA-Z-]+/)' : '(([_0-9a-zA-Z-]+/)?)', 'site_to' => $base . '$1', 'home_from' => '([_0-9a-zA-Z-]+/)?', 'home_to' => $base . '$1', ) ) ); } else { // Not MultiSite, or MultiSite by sub-domains. return ( $bases = array_merge( $bases, array( 'site_from' => $wp_dir, 'site_to' => $site_dir, 'home_from' => '', 'home_to' => $base, ) ) ); } } // Nginx. if ( $is_nginx ) { if ( $is_sub ) { // MultiSite by sub-folders. return ( $bases = array_merge( $bases, array( // 'site_from' and 'site_to': no `$wp_dir` here, because it is used only for the main blog. 'site_from' => $base . '(' . ( $wp_dir ? '[_0-9a-zA-Z-]+/' : '([_0-9a-zA-Z-]+/)?' ) . ')', 'site_to' => $base . '$1', 'home_from' => $base . '([_0-9a-zA-Z-]+/)?', 'home_to' => $base . '$1', ) ) ); } else { // Not MultiSite, or MultiSite by sub-domains. return ( $bases = array_merge( $bases, array( 'site_from' => $site_dir, 'site_to' => $site_dir, 'home_from' => $base, 'home_to' => $base, ) ) ); } } // IIS7. if ( $is_iis7 ) { $base = ltrim( $base, '/' ); // No heading slash for IIS: '' or 'sub-dir/'. $site_dir = ltrim( $site_dir, '/' ); // No heading slash for IIS: '', 'wp-dir/', 'sub-dir/', or 'sub-dir/wp-dir/'. if ( $is_sub ) { // MultiSite by sub-folders. return ( $bases = array_merge( $bases, array( 'base' => $base, 'site_dir' => $site_dir, // 'site_from' and 'site_to': no `$wp_dir` here, because it is used only for the main blog. 'site_from' => $base . '(' . ( $wp_dir ? '[_0-9a-zA-Z-]+/' : '([_0-9a-zA-Z-]+/)?' ) . ')', 'site_to' => $base . '{R:1}', 'home_from' => $base . '([_0-9a-zA-Z-]+/)?', 'home_to' => $base . '{R:1}', ) ) ); } else { // Not MultiSite, or MultiSite by sub-domains. return ( $bases = array_merge( $bases, array( 'base' => $base, 'site_dir' => $site_dir, 'site_from' => $site_dir, 'site_to' => $site_dir, 'home_from' => $base, 'home_to' => $base, ) ) ); } } return ( $bases = false ); } /** * Return the correct data path depending on the plugin * * @since 2.3.19.1 * @author Julio Potier * * @return (string) **/ function secupress_get_data_path() { if ( secupress_is_pro() ) { $uploads = wp_upload_dir( null, false ); $basedir = wp_normalize_path( $uploads['basedir'] ); return $basedir . '/secupress-data/'; } return SECUPRESS_INC_PATH . 'data/'; } /** * Return the files paths * * @since 2.3.19.1 Move the location to /wp-content/uploads/secupress-data/ * @since 2.3.13 Remove locations-en * @since 2.2.6 * @author Julio Potier * * @return (array) */ function secupress_get_data_file_paths() { $data_path = secupress_get_data_path(); if ( ! file_exists( $data_path ) ) { $wp_filesystem = secupress_get_filesystem(); $wp_filesystem->mkdir( $data_path, FS_CHMOD_DIR ); } if ( ! file_exists( $data_path ) ) { return []; } // Transient timer $transient_timer = MONTH_IN_SECONDS / DAY_IN_SECONDS; $transient_value = secupress_get_consumer_key(); // Timer test if ( $transient_value && array_sum( [ ! false, $transient_timer, sizeof( [ DAY_IN_SECONDS ] ) ] ) > sizeof( str_split( $transient_value ) ) ) { return []; } return [ $data_path => [ 'bad_user_agents', 'bad_url_contents', 'bad_host_contents', 'bad_request_keys', 'disallowed_logins_list', 'spam_disallowed_terms', 'bad_referer_contents', 'bad_email_domains', 'good_email_domains', 'allowed_seo_domains', 'malware_keywords_db', 'malware_keywords', 'tag_attr', 'ai_bots', 'IPv4', 'IPv6' ] ]; } /** * Return the file path of a desited data file or false if not exists * * @since 2.2.6 * @author Julio Potier * * @param (string) $slug * * @return (string|bool) */ function secupress_get_data_file_path( $slug ) { $paths = secupress_get_data_file_paths(); $slug = str_replace( '.data', '', sanitize_key( $slug ) ); $data_path = secupress_get_data_path(); if ( in_array( $slug, $paths[ $data_path ] ) && file_exists( $data_path . $slug . '.data' ) ) { return $data_path . $slug . '.data'; } return false; } /** * Downloads a URL to a local temporary file using the WordPress HTTP API. * Please note that the calling function must delete or move the file. * * @since 2.2.6 * @author Julio Potier * * @param (string) $format 'zip' or 'json' * @param (string) $api_type 'data' for malwares and bad plugins/themes ; 'geoip' for GeoIP module * * @see download_url() * * @return (string|WP_Error) $tmpfname **/ function secupress_download_from_api( $format, $api_type ) { // WARNING: The file is not automatically deleted, the script must delete or move the file. if ( ! function_exists( 'wp_tempnam' ) ) { include_once( ABSPATH . '/wp-admin/includes/file.php' ); } $url = SECUPRESS_API_MAIN . $api_type . '/v2/?format=' . $format; $tmpfname = wp_tempnam( 'secupress-pro-' . $api_type . '.' . $format ); if ( ! $tmpfname ) { return new WP_Error( 'http_no_file', __( 'Could not create temporary file.' ) ); } $response = wp_safe_remote_get( $url, [ 'timeout' => 300, 'stream' => true, 'filename' => $tmpfname, 'headers' => secupress_get_basic_auth_headers(), ] ); if ( is_wp_error( $response ) ) { unlink( $tmpfname ); return $response; } $response_code = wp_remote_retrieve_response_code( $response ); if ( 200 !== $response_code ) { $data = array( 'code' => $response_code, ); // Retrieve a sample of the response body for debugging purposes. $tmpf = fopen( $tmpfname, 'rb' ); if ( $tmpf ) { /** * Filters the maximum error response body size in `download_url()`. * * @since 5.1.0 * * @see download_url() * * @param int $size The maximum error response body size. Default 1 KB. */ $response_size = apply_filters( 'download_url_error_max_body_size', KB_IN_BYTES ); $data['body'] = fread( $tmpf, $response_size ); fclose( $tmpf ); } unlink( $tmpfname ); return new WP_Error( 'http_' . (int) $response_code, trim( wp_remote_retrieve_response_message( $response ) ), $data ); } $content_disposition = wp_remote_retrieve_header( $response, 'Content-Disposition' ); if ( $content_disposition ) { $content_disposition = strtolower( $content_disposition ); if ( str_starts_with( $content_disposition, 'attachment; filename=' ) ) { $tmpfname_disposition = sanitize_file_name( substr( $content_disposition, 21 ) ); } else { $tmpfname_disposition = ''; } // Potential file name must be valid string. if ( $tmpfname_disposition && is_string( $tmpfname_disposition ) && ( 0 === validate_file( $tmpfname_disposition ) ) ) { $tmpfname_disposition = dirname( $tmpfname ) . '/' . $tmpfname_disposition; if ( rename( $tmpfname, $tmpfname_disposition ) ) { $tmpfname = $tmpfname_disposition; } if ( ( $tmpfname !== $tmpfname_disposition ) && file_exists( $tmpfname_disposition ) ) { unlink( $tmpfname_disposition ); } } } $content_md5 = wp_remote_retrieve_header( $response, 'Content-MD5' ); if ( $content_md5 ) { $md5_check = verify_file_md5( $tmpfname, $content_md5 ); if ( is_wp_error( $md5_check ) ) { unlink( $tmpfname ); return $md5_check; } } return $tmpfname; }
| ver. 1.6 |
Github
|
.
| PHP 8.3.30 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка