public function EventLoginFailure($username) { list($y, $m, $d) = explode('-', date('Y-m-d')); $tt1 = new WSAL_DB_Occurrence(); $tt2 = new WSAL_DB_Meta(); $occ = WSAL_DB_Occurrence::LoadMultiQuery(' SELECT * FROM `' . $tt1->GetTable() . '` WHERE alert_id = %d AND site_id = %d AND (created_on BETWEEN %d AND %d) AND id IN ( SELECT occurrence_id as id FROM `' . $tt2->GetTable() . '` WHERE (name = "ClientIP" AND value = %s) OR (name = "Username" AND value = %s) GROUP BY occurrence_id HAVING COUNT(*) = 2 ) ', array(1002, function_exists('get_current_blog_id') ? get_current_blog_id() : 0, mktime(0, 0, 0, $m, $d, $y), mktime(0, 0, 0, $m, $d + 1, $y) - 1, json_encode(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : ''), json_encode($username))); $occ = count($occ) ? $occ[0] : null; if ($occ && $occ->IsLoaded()) { // update existing record $occ->SetMetaValue('Attempts', $occ->GetMetaValue('Attempts', 0) + 1); $occ->created_on = current_time('timestamp'); $occ->Save(); } else { // create a new record $this->plugin->alerts->Trigger(1002, array('Username' => $username, 'Attempts' => 1)); } }
public function CleanUp() { $now = current_time('timestamp'); $max_sdate = $this->plugin->settings->GetPruningDate(); $max_count = $this->plugin->settings->GetPruningLimit(); $is_date_e = $this->plugin->settings->IsPruningDateEnabled(); $is_limt_e = $this->plugin->settings->IsPruningLimitEnabled(); $max_stamp = $now - (strtotime($max_sdate) - $now); $cnt_items = WSAL_DB_Occurrence::Count(); $max_items = max($cnt_items - $max_count + 1, 0); if (!$is_date_e && !$is_limt_e) { return; } // pruning disabled $query = new WSAL_DB_OccurrenceQuery('WSAL_DB_Occurrence'); $query->order[] = 'created_on ASC'; if ($is_date_e) { $query->Where('created_on < %d', array($max_stamp)); } if ($is_limt_e) { $query->length = (int) $max_items; } $count = $query->Count(); if (!$count) { return; } // nothing to delete // delete data $query->Delete(); // keep track of what we're doing $this->plugin->alerts->Trigger(03, array('Message' => 'Running system cleanup.', 'Query SQL' => $query->GetSql(), 'Query Args' => $query->GetArgs()), true); // notify system do_action('wsal_prune', $count, vsprintf($query->GetSql(), $query->GetArgs())); }
public function RenderWidget() { $results = WSAL_DB_Occurrence::LoadMulti(' 1 ORDER BY created_on DESC LIMIT ' . $this->_plugin->settings->GetDashboardWidgetMaxAlerts()); ?> <div><?php if (!count($results)) { ?> <p><?php _e('No alerts found.', 'wp-security-audit-log'); ?> </p><?php } else { ?> <table class="wp-list-table widefat" cellspacing="0" cellpadding="0" style="display: block; overflow-x: auto;"> <thead> <th class="manage-column" style="width: 15%;" scope="col"><?php _e('User', 'wp-security-audit-log'); ?> </th> <th class="manage-column" style="width: 85%;" scope="col"><?php _e('Description', 'wp-security-audit-log'); ?> </th> </thead> <tbody><?php $url = 'admin.php?page=' . $this->_plugin->views->views[0]->GetSafeViewName(); $fmt = array(new WSAL_Views_AuditLogList_Internal($this->_plugin), 'meta_formatter'); foreach ($results as $entry) { ?> <tr> <td><?php echo ($un = $entry->GetUsername()) ? esc_html($un) : '<i>unknown</i>'; ?> </td> <td> <a href="<?php echo $url . '#Event' . $entry->id; ?> "><?php echo $entry->GetMessage($fmt); ?> </a> </td> </tr><?php } ?> </tbody> </table><?php } ?> </div><?php }
public function CleanUp() { $now = current_time('timestamp'); $max_count = $this->plugin->settings->GetPruningLimit(); $max_sdate = $this->plugin->settings->GetPruningDate(); $max_stamp = $now - (strtotime($max_sdate) - $now); $cnt_items = WSAL_DB_Occurrence::Count(); if ($cnt_items == $max_count) { return; } $max_items = max($cnt_items - $max_count + 1, 0); $is_date_e = $this->plugin->settings->IsPruningDateEnabled(); $is_limt_e = $this->plugin->settings->IsPruningLimitEnabled(); switch (true) { case $is_date_e && $is_limt_e: $cond = 'created_on < %d ORDER BY created_on ASC LIMIT %d'; $args = array($max_stamp, $max_items); break; case $is_date_e && !$is_limt_e: $cond = 'created_on < %d'; $args = array($max_stamp); break; case !$is_date_e && $is_limt_e: $cond = '1 ORDER BY created_on ASC LIMIT %d'; $args = array($max_items); break; case !$is_date_e && !$is_limt_e: return; } if (!isset($cond)) { return; } $items = WSAL_DB_Occurrence::LoadMulti($cond, $args); if (!count($items)) { return; } foreach ($items as $item) { $item->Delete(); } do_action('wsal_prune', $items, vsprintf($cond, $args)); }
public function AjaxRefresh() { if (!$this->_plugin->settings->CurrentUserCan('view')) { die('Access Denied.'); } if (!isset($_REQUEST['logcount'])) { die('Log count parameter expected.'); } $old = (int) $_REQUEST['logcount']; $max = 40; // 40*500msec = 20sec session_write_close(); // fixes session lock issue do { $new = WSAL_DB_Occurrence::Count(); usleep(500000); // 500msec } while ($old == $new && --$max > 0); echo $old == $new ? 'false' : $new; die; }
public function EventLoginFailure($username) { list($y, $m, $d) = explode('-', date('Y-m-d')); $ip = $this->plugin->settings->GetMainClientIP(); $tt1 = new WSAL_DB_Occurrence(); $tt2 = new WSAL_DB_Meta(); $username = $_POST["log"]; $newAlertCode = 1003; $user = get_user_by('login', $username); $site_id = function_exists('get_current_blog_id') ? get_current_blog_id() : 0; if ($user) { $newAlertCode = 1002; $userRoles = $this->plugin->settings->GetCurrentUserRoles($user->roles); } if ($this->IsPastLoginFailureLimit($ip, $site_id, $user)) { return; } if ($newAlertCode == 1002) { if (!$this->plugin->alerts->CheckEnableUserRoles($username, $userRoles)) { return; } $occ = WSAL_DB_Occurrence::LoadMultiQuery(' SELECT occurrence.* FROM `' . $tt1->GetTable() . '` occurrence INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id and ipMeta.name = "ClientIP" and ipMeta.value = %s INNER JOIN `' . $tt2->GetTable() . '` usernameMeta on usernameMeta.occurrence_id = occurrence.id and usernameMeta.name = "Username" and usernameMeta.value = %s WHERE occurrence.alert_id = %d AND occurrence.site_id = %d AND (created_on BETWEEN %d AND %d) GROUP BY occurrence.id', array(json_encode($ip), json_encode($username), 1002, $site_id, mktime(0, 0, 0, $m, $d, $y), mktime(0, 0, 0, $m, $d + 1, $y) - 1)); $occ = count($occ) ? $occ[0] : null; if ($occ && $occ->IsLoaded()) { // update existing record exists user $this->IncrementLoginFailure($ip, $site_id, $user); $new = $occ->GetMetaValue('Attempts', 0) + 1; if ($new > $this->GetLoginFailureLogLimit()) { $new = $this->GetLoginFailureLogLimit() . '+'; } $occ->SetMetaValue('Attempts', $new); $occ->SetMetaValue('Username', $username); //$occ->SetMetaValue('CurrentUserRoles', $userRoles); $occ->created_on = null; $occ->Save(); } else { // create a new record exists user $this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1, 'Username' => $username, 'CurrentUserRoles' => $userRoles)); } } else { $occUnknown = WSAL_DB_Occurrence::LoadMultiQuery(' SELECT occurrence.* FROM `' . $tt1->GetTable() . '` occurrence INNER JOIN `' . $tt2->GetTable() . '` ipMeta on ipMeta.occurrence_id = occurrence.id and ipMeta.name = "ClientIP" and ipMeta.value = %s WHERE occurrence.alert_id = %d AND occurrence.site_id = %d AND (created_on BETWEEN %d AND %d) GROUP BY occurrence.id', array(json_encode($ip), 1003, $site_id, mktime(0, 0, 0, $m, $d, $y), mktime(0, 0, 0, $m, $d + 1, $y) - 1)); $occUnknown = count($occUnknown) ? $occUnknown[0] : null; if ($occUnknown && $occUnknown->IsLoaded()) { // update existing record not exists user $this->IncrementLoginFailure($ip, $site_id, false); $new = $occUnknown->GetMetaValue('Attempts', 0) + 1; if ($new > $this->GetLoginFailureLogLimit()) { $new = $this->GetLoginFailureLogLimit() . '+'; } $occUnknown->SetMetaValue('Attempts', $new); $occUnknown->created_on = null; $occUnknown->Save(); } else { // create a new record not exists user $this->plugin->alerts->Trigger($newAlertCode, array('Attempts' => 1)); } } }
public function column_default(WSAL_DB_Occurrence $item, $column_name) { switch ($column_name) { case 'read': return '<span class="log-read log-read-' . ($item->is_read ? 'old' : 'new') . '" title="' . __('Click to toggle.', 'wp-security-audit-log') . '"></span>'; case 'type': return str_pad($item->alert_id, 4, '0', STR_PAD_LEFT); case 'code': $code = $this->_plugin->alerts->GetAlert($item->alert_id); $code = $code ? $code->code : 0; $const = (object) array('name' => 'E_UNKNOWN', 'value' => 0, 'description' => __('Unknown error code.', 'wp-security-audit-log')); $const = $this->_plugin->constants->GetConstantBy('value', $code, $const); return '<span class="log-type log-type-' . $const->value . '" title="' . esc_html($const->name . ': ' . $const->description) . '"></span>'; case 'crtd': return $item->created_on ? str_replace('$$$', substr(number_format(fmod($item->created_on + $this->_gmt_offset_sec, 1), 3), 2), date('Y-m-d<\\b\\r>h:i:s.$$$&\\n\\b\\s\\p;A', $item->created_on + $this->_gmt_offset_sec)) : '<i>unknown</i>'; case 'user': $username = $item->GetUsername(); if ($username && ($user = get_user_by('login', $username))) { $image = get_avatar($user->ID, 32); $uhtml = '<a href="' . admin_url('user-edit.php?user_id=' . $user->ID) . '" target="_blank">' . esc_html($user->display_name) . '</a>'; $roles = $item->GetUserRoles(); $roles = is_array($roles) && count($roles) ? __(esc_html(ucwords(implode(', ', $roles)))) : '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>'; } else { $image = get_avatar(0, 32); $uhtml = '<i>' . __('Unknown', 'wp-security-audit-log') . '</i>'; $roles = '<i>' . __('System', 'wp-security-audit-log') . '</i>'; } return $image . $uhtml . '<br/>' . $roles; case 'scip': return !is_null($item->GetSourceIP()) ? esc_html($item->GetSourceIP()) : '<i>unknown</i>'; case 'site': $info = get_blog_details($item->site_id, true); return !$info ? 'Unknown Site ' . $item->site_id : '<a href="' . esc_attr($info->siteurl) . '">' . esc_html($info->blogname) . '</a>'; case 'mesg': return '<div id="Event' . $item->id . '">' . $item->GetMessage(array($this, 'meta_formatter')) . '</div>'; case 'data': $url = admin_url('admin-ajax.php') . '?action=AjaxInspector&occurrence=' . $item->id; return '<a class="more-info thickbox" title="' . __('Alert Data Inspector', 'wp-security-audit-log') . '"' . ' href="' . $url . '&TB_iframe=true&width=600&height=550">…</a>'; default: return isset($item->{$column_name}) ? esc_html($item->{$column_name}) : 'Column "' . esc_html($column_name) . '" not found'; } }
public function prepare_items() { $per_page = $this->_plugin->settings->GetViewPerPage(); $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); //$this->process_bulk_action(); $bid = (int) $this->get_view_site_id(); $sql = ($bid ? "site_id={$bid}" : '1') . ' ORDER BY created_on DESC'; $data = WSAL_DB_Occurrence::LoadMulti($sql, array()); if (count($data)) { $this->_orderby = !empty($_REQUEST['orderby']) && isset($sortable[$_REQUEST['orderby']]) ? $_REQUEST['orderby'] : 'created_on'; $this->_order = !empty($_REQUEST['order']) && $_REQUEST['order'] == 'asc' ? 'asc' : 'desc'; if (isset($data[0]->{$this->_orderby})) { $numorder = in_array($this->_orderby, array('code', 'type', 'created_on')); usort($data, array($this, $numorder ? 'reorder_items_int' : 'reorder_items_str')); } } $current_page = $this->get_pagenum(); $total_items = count($data); $data = array_slice($data, ($current_page - 1) * $per_page, $per_page); $this->items = $data; $this->set_pagination_args(array('total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page))); }