Completed
Push — add/support-for-multi-site-res... ( 2212a9...df602e )
by
unknown
21:07 queued 11:04
created

VP_Site_Scanner::_scan_clean_up()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 2
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
// don't call the file directly
3
defined( 'ABSPATH' ) or die();
4
5
include_once dirname( __FILE__ ) . '/vp-scanner.php';
6
7
if ( !function_exists( 'apply_filters_ref_array' ) ) :
8
9
function apply_filters_ref_array($tag, $args) {
10
	global $wp_filter, $merged_filters, $wp_current_filter;
11
12
	// Do 'all' actions first
13
	if ( isset($wp_filter['all']) ) {
14
		$all_args = func_get_args();
15
		$wp_current_filter[] = $tag;
16
		_wp_call_all_hook($all_args);
17
	}
18
19
	if ( !isset($wp_filter[$tag]) ) {
20
		if ( isset($wp_filter['all']) )
21
			array_pop($wp_current_filter);
22
			return $args[0];
23
	}
24
25
	if ( !isset($wp_filter['all']) )
26
		$wp_current_filter[] = $tag;
27
28
	// Sort
29
	if ( !isset( $merged_filters[ $tag ] ) ) {
30
		ksort($wp_filter[$tag]);
31
		$merged_filters[ $tag ] = true;
32
	}
33
34
	reset( $wp_filter[ $tag ] );
35
36
	do {
37
		foreach( (array) current($wp_filter[$tag]) as $the_ )
38
			if ( !is_null($the_['function']) )
39
				$args[0] = call_user_func_array($the_['function'], array_slice($args, 0, (int) $the_['accepted_args']));
40
41
	} while ( next($wp_filter[$tag]) !== false );
42
43
	array_pop( $wp_current_filter );
44
45
	return $args[0];
46
}
47
48
endif;
49
50
class VP_Site_Scanner {
51
	function __construct() {
52
		// Only scan once in multisites.
53
		if( function_exists( 'is_main_site' ) && !is_main_site() )
54
			return;
55
		add_action( 'vp_scan_site'      , array( $this, '_scan_site') );
56
		add_filter( 'cron_schedules'    , array( $this, '_custom_cron' ) );
57
		add_action( 'vp_scan_next_batch', array( $this, '_scan_batch' ) );
58
59
		$signatures = get_option( '_vp_signatures' );
60
		if ( $signatures && ! wp_next_scheduled( 'vp_scan_site' ) )
61
			wp_schedule_event( time(), 'daily', 'vp_scan_site' );
62
		if ( $signatures && ! wp_next_scheduled( 'vp_scan_next_batch' ) )
63
			wp_schedule_event( time(), 'five_minutes_interval', 'vp_scan_next_batch' );
64
	}
65
66
	function _custom_cron( $schedules ) {
67
		$schedules['five_minutes_interval'] = array(
68
			'interval' => 300,
69
			'display'  => __( 'Once every five minutes' , 'vaultpress'),
70
		);
71
		return $schedules;
72
	}
73
74
	function _scan_site() {
75
		if ( !get_option( '_vp_current_scan' ) ) {
76
			$ignore_symlinks = get_option( '_vp_ignore_symlinks', false );
77
			$paths = array( 'root' => new VP_FileScan( ABSPATH, $ignore_symlinks ) );
78
79
			// Is WP_CONTENT_DIR inside ABSPATH?
80
			if ( is_dir( WP_CONTENT_DIR ) && strpos( realpath( WP_CONTENT_DIR ), realpath( ABSPATH ) . DIRECTORY_SEPARATOR ) !== 0 )
81
				$paths['content'] = new VP_FileScan( WP_CONTENT_DIR, $ignore_symlinks );
82
83
			// Is WP_PLUGIN_DIR inside ABSPATH or WP_CONTENT_DIR?
84 View Code Duplication
			if ( is_dir( WP_PLUGIN_DIR ) && strpos( realpath( WP_PLUGIN_DIR ), realpath( WP_CONTENT_DIR ) . DIRECTORY_SEPARATOR ) !== 0 && strpos( realpath( WP_PLUGIN_DIR ), realpath( ABSPATH ) . DIRECTORY_SEPARATOR ) !== 0 )
85
				$paths['plugins'] = new VP_FileScan( WP_PLUGIN_DIR, $ignore_symlinks );
86
87
			// Is WPMU_PLUGIN_DIR inside ABSPATH or WP_CONTENT_DIR?
88 View Code Duplication
			if ( is_dir( WPMU_PLUGIN_DIR ) && strpos( realpath( WPMU_PLUGIN_DIR ), realpath( WP_CONTENT_DIR ) . DIRECTORY_SEPARATOR ) !== 0 && strpos( realpath( WPMU_PLUGIN_DIR ), realpath( ABSPATH ) . DIRECTORY_SEPARATOR ) !== 0 )
89
				$paths['mu-plugins'] = new VP_FileScan( WPMU_PLUGIN_DIR, $ignore_symlinks );
90
91
			update_option( '_vp_current_scan', $paths );
92
		}
93
	}
94
95
	function _scan_clean_up( &$paths, $type = null ) {
96
		if( is_array( $paths ) )
97
			unset( $paths[$type] );
98
		if ( empty( $paths ) || !is_array( $paths ) ) {
99
			delete_option( '_vp_current_scan' );
100
			return true;
101
		}
102
		return false;
103
	}
104
105
	function _scan_batch() {
106
		$paths = get_option( '_vp_current_scan' );
107
		if ( empty( $paths ) || $this->_scan_clean_up( $paths ) )
108
			return false;
109
110
		if ( ! is_array( $paths ) ) {
111
			return false;
112
		}
113
114
		reset( $paths );
115
116
		$type    = null;
117
		$current = false;
118
		foreach ( $paths as $type => $current ) {
119
			break;
120
		}
121
122
		if ( !is_object( $current ) || empty( $current->last_dir ) )
123
			return $this->_scan_clean_up( $paths, $type );
124
125
		$default_batch_limit = 400;
126
		if ( ! function_exists( 'set_time_limit' ) || ! @set_time_limit( 0 ) ) {
127
			$default_batch_limit = 100; // avoid timeouts
128
		}
129
130
		$GLOBALS['vp_signatures'] = get_option( '_vp_signatures' );
131
		if ( empty( $GLOBALS['vp_signatures'] ) )
132
			return false;
133
134
		$limit = get_option( '_vp_batch_file_size', $default_batch_limit );
135
		$files = $current->get_files( $limit );
136
137
		// No more files to scan.
138
		if ( !$current->last_dir || count( $files ) < $limit )
139
			unset( $paths[$type] );
140
141
		update_option( '_vp_current_scan', $paths );
142
		$results = array();
143
		foreach ( $files as $file ) {
144
			$verdict = vp_scan_file( $file );
145
			if ( !empty( $verdict ) )
146
				$results[$file] = array( 'hash' => @md5_file( $file ), 'verdict' => $verdict );
147
		}
148
149
		if ( !empty( $results ) ) {
150
			$vaultpress = VaultPress::init();
151
			$vaultpress->add_ping( 'security', array( 'suspicious_v2' => $results ) );
152
		}
153
	}
154
155
	static function &init() {
156
		static $instance = false;
157
		if ( !$instance )
158
			$instance = new VP_Site_Scanner();
159
		return $instance;
160
	}
161
}
162
VP_Site_Scanner::init();
163