', 'RewriteEngine On' ); foreach ( self::groups() as $g ) { if ( $seen ) { $out[] = 'RewriteCond %{ENV:REDIRECT_RP_EVENT} ^$'; $out[] = 'RewriteCond ' . $disk . ' -f'; $out[] = 'RewriteRule "' . $g[0] . '" ' . $probe . ' [L,NC,E=RP_EVENT:' . $g[1] . ',E=RP_FILE:' . $file . ']'; } $out[] = 'RewriteCond %{ENV:REDIRECT_RP_EVENT} ^$'; $out[] = 'RewriteRule "' . $g[0] . '" - [F,L,NC]'; } $out[] = ''; $out[] = ''; $out[] = ''; foreach ( self::groups() as $g ) { $out[] = 'RedirectMatch 403 "' . $g[0] . '"'; } $out[] = ''; $out[] = ''; return $out; } public static function nginx() { return array( 'location ~ (^|/)\.' . self::DOT_NAMES . '(\.|/|$) { return 403; }', 'location ~ \.' . self::ENDINGS . '$ { return 403; }', 'location ~ ' . self::BACKUPS . '$ { return 403; }', 'location ~ (^|/)' . self::NAMES . '$ { return 403; }', ); } public static function server( array $server ) { $s = isset( $server['SERVER_SOFTWARE'] ) ? strtolower( (string) $server['SERVER_SOFTWARE'] ) : ''; if ( false !== strpos( $s, 'nginx' ) ) { return 'nginx'; } if ( false !== strpos( $s, 'apache' ) || false !== strpos( $s, 'litespeed' ) ) { return 'apache'; } return 'other'; } public static function apply( $on ) { if ( 'apache' !== self::server( $_SERVER ) ) { return 'skipped'; } if ( ! function_exists( 'insert_with_markers' ) ) { require_once ABSPATH . 'wp-admin/includes/misc.php'; } if ( ! function_exists( 'get_home_path' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } $file = get_home_path() . '.htaccess'; if ( ! $on && ! file_exists( $file ) ) { return 'removed'; } if ( file_exists( $file ) ? ! wp_is_writable( $file ) : ! wp_is_writable( dirname( $file ) ) ) { return 'failed'; } self::one_block( $file ); $text = file_exists( $file ) ? (string) file_get_contents( $file ) : ''; $text = self::without( $text ); if ( $on ) { $block = implode( "\n", array_merge( array( '# BEGIN ' . self::MARKER ), self::rules(), array( '# END ' . self::MARKER ) ) ) . "\n\n"; if ( 1 === preg_match( '/^# END Rabbitproof lock\r?\n(\r?\n)?/m', $text, $m, PREG_OFFSET_CAPTURE ) ) { $at = $m[0][1] + strlen( $m[0][0] ); $text = substr( $text, 0, $at ) . $block . substr( $text, $at ); } else { $text = $block . $text; } } if ( false === file_put_contents( $file, $text, LOCK_EX ) ) { return 'failed'; } return $on ? 'written' : 'removed'; } public static function without( $text ) { return (string) preg_replace( '/^# BEGIN ' . preg_quote( self::MARKER, '/' ) . "\r?\n.*?^# END " . preg_quote( self::MARKER, '/' ) . "\r?\n(\r?\n)?/ms", '', (string) $text ); } public static function one_block( $file ) { if ( ! is_readable( $file ) || ! wp_is_writable( $file ) ) { return; } $lines = preg_split( '/\r\n|\n|\r/', (string) file_get_contents( $file ) ); $out = array(); $seen = 0; $skip = false; foreach ( $lines as $line ) { if ( '# BEGIN ' . self::MARKER === trim( $line ) ) { $seen++; $skip = $seen > 1; } if ( ! $skip ) { $out[] = $line; } if ( '# END ' . self::MARKER === trim( $line ) ) { $skip = false; } } if ( $seen > 1 ) { file_put_contents( $file, implode( "\n", $out ), LOCK_EX ); } } public static function written() { if ( ! function_exists( 'get_home_path' ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; } $file = get_home_path() . '.htaccess'; if ( ! is_readable( $file ) ) { return false; } $text = (string) file_get_contents( $file ); return false !== strpos( $text, '# BEGIN ' . self::MARKER . "\n" ) && false !== strpos( $text, 'RedirectMatch 403' ); } const FORMAT = '2'; public static function register() { add_action( 'admin_init', array( __CLASS__, 'refresh' ) ); } public static function refresh() { if ( self::FORMAT === get_option( 'rabbitproof_files_format' ) || ! current_user_can( 'manage_options' ) ) { return; } update_option( 'rabbitproof_files_format', self::FORMAT, false ); if ( Rabbitproof_Options::get( 'scanners' ) && 'apache' === self::server( $_SERVER ) ) { self::apply( true ); } } public static function activate() { self::apply( (bool) Rabbitproof_Options::get( 'scanners' ) ); } public static function remove() { self::apply( false ); } public static function note( $on ) { if ( ! $on ) { return array( 'text' => '', 'code' => array() ); } $server = self::server( $_SERVER ); if ( 'apache' === $server && self::written() ) { return array( 'text' => '', 'code' => array() ); } if ( 'nginx' === $server ) { return array( 'text' => __( 'One more step for your host: your server (nginx) needs these lines added to its settings, so these files stay private even if they exist. Send them to your host.', 'rabbitproof' ), 'code' => self::nginx() ); } return array( 'text' => __( 'One more step for your host: the plugin could not add its lines to your server. Send these to your host to add to the .htaccess file of your website.', 'rabbitproof' ), 'code' => self::rules( false ) ); } }