/* TODO: - Audit collapse animation is jerky and lame - Suppress errors in cron script and schedule - Cron script shouldn't wallop json files while it's running - Update styles and icons in UI when files are (un)ignored - Add option to show all ignores/acks - Add option to clear all ignores/acks - Adding directory aknowlegement could be useful for plugin updates and new sites. */ require_once('template.php'); $errors = array(); $sites = array(); $slugs = array(); $audits = array(); $ignores = array(); $changed_files = array(); $unacked_files = array(); $unacked_scripts = array(); $unacked_sites = array(); $audit_dir = 'json'; $warn_age = 1 * 24 * 60 * 60; # 1 day, 24 hours, or seconds # need to keep this in sync with vhost-audit.pl $scripts = array('/.php$/', '/.htaccess$/', '/.js$/'); $sites_file = 'sites.txt'; if ( ($sites = @file($sites_file, FILE_IGNORE_NEW_LINES)) !== FALSE ) { $site_count = count($sites); sort($sites); } else { $errors[] = 'Could not open sites file, ' . $sites_file; } foreach ($sites as $site) { $parts = explode('/', $site); $hostname = $parts[count($parts) -2]; $slugs[$site] = preg_replace('/\./', '_', $hostname); $audit_file = $audit_dir . '/' . $hostname . '.json'; $ignore_file = $audit_dir . '/' . $hostname . '-ignore.json'; # pull in a site's ignore file if ( file_exists($ignore_file) ) { if ( ($ignore_json = @file_get_contents($ignore_file)) !== FALSE ) { $ignore_json = utf8_encode($ignore_json); $ignore = @json_decode($ignore_json, true); if ($ignore === null) { $ignore = array(); } $ignores[$site] = $ignore; } else { $errors[] = 'Could not open ignore file, ' . $ignore_file; } } # pull in a site's audit file if ( file_exists($audit_file) ) { if ( ($audit_json = @file_get_contents($audit_file)) !== FALSE ) { $audit_json = utf8_encode($audit_json); $audit = @json_decode($audit_json, true); if ($audit === null) { $audit = array('data' => array()); } ksort($audit['data']); foreach ( array_keys($audit['data']) as $date) { if ( is_array($audit['data'][$date]['files']) ) { ksort($audit['data'][$date]['files']); } else { $audit['data'][$date]['files'] = array(); } foreach ( $audit['data'][$date]['files'] as $file => $action ) { $dir = dirname($file); if (substr($dir, -1) !== '/') { $dir .= '/'; } $audit['data'][$date]['files'][$file] = array('action' => $action); if ( isset($ignores[$site][$file]) ) { if ( $ignores[$site][$file]['action'] == 'acknowledge' ) { if ( $ignores[$site][$file]['date'] > $date ) { $audit['data'][$date]['files'][$file]['status'] = 'acknowledge'; } } elseif ( $ignores[$site][$file]['action'] == 'ignore_file' ) { $audit['data'][$date]['files'][$file]['status'] = 'ignore_file'; } } elseif ( isset($ignores[$site][$dir]['action']) ) { $audit['data'][$date]['files'][$file]['status'] = 'ignore_dir'; } else { $unacked_files[] = $site . $file; $is_script = false; foreach ($scripts AS $script) { if ( preg_match($script, $file) ) { $is_script = true; break; } } if ( $is_script ) { $unacked_scripts[] = $site . $file; $unacked_sites[$site] = true; } } } } $lastrun = $audit['lastrun']; $audits[$site] = $audit; } else { $errors[] = 'Could not open audit file, ' . $audit_file; } } else { $errors[] = "Audit file ($audit_file) not found"; } $tot_changes += $audit['changes']; $tot_scripts += $audit['scripts']; } #print_r($unacked_scripts);exit; $tot_unacked_changes = count($unacked_files); $tot_unacked_scripts = count($unacked_scripts); $unacked_sites = array_keys($unacked_sites); #echo('
Audits: '); #print_r($audits); #echo('Ignores: '); #print_r($ignores); #echo(''); #exit; if ( $_SERVER['HTTP_ACCEPT'] == 'application/json' || $_SERVER['CONTENT_TYPE'] == 'application/json') { if ( $tot_unacked_scripts == 0 ) { $message = 'OK'; } else { $message = 'Unacknowledged script changes in: ' . join(', ', $unacked_sites); } header('Content-type: application/json'); $response = array( 'sites' => $site_count, 'changes' => $tot_changes, 'scripts' => $tot_scripts, 'unacked_changes' => $tot_unacked_changes, 'unacked_scripts' => $tot_unacked_scripts, 'unacked_sites' => $unacked_sites, 'message' => $message ); echo(json_encode($response, JSON_PRETTY_PRINT)); exit; } else { $T = new Template('templates/index.php'); $T->set('errors', $errors); $T->set('message', $message); $T->set('sites', $sites); $T->set('site_count', $site_count); $T->set('slugs', $slugs); $T->set('ignores', $ignores); $T->set('audits', $audits); $T->set('warn_age', $warn_age); $T->set('scripts', $scripts); $T->set('tot_changes', $tot_changes); $T->set('tot_scripts', $tot_scripts); $T->set('tot_unacked_changes', $tot_unacked_changes); $T->set('tot_unacked_scripts', $tot_unacked_scripts); $T->set('unacked_sites', $unacked_sites); echo($T->fetch()); exit; } ?>