mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-29 08:45:12 +02:00
Merge branch 'ent-1290-monitorizacion-de-windows-module_logevent' into 'develop'
Ent 1290 monitorizacion de windows module logevent See merge request artica/pandorafms!975
This commit is contained in:
commit
1898896e96
@ -3,7 +3,7 @@ if DEBUG
|
||||
PandoraAgent_SOURCES = misc/pandora_file.cc modules/pandora_data.cc modules/pandora_module_factory.cc modules/pandora_module.cc modules/pandora_module_list.cc modules/pandora_module_plugin.cc modules/pandora_module_inventory.cc modules/pandora_module_freememory.cc modules/pandora_module_exec.cc modules/pandora_module_perfcounter.cc modules/pandora_module_proc.cc modules/pandora_module_tcpcheck.cc modules/pandora_module_freememory_percent.cc modules/pandora_module_freedisk.cc modules/pandora_module_freedisk_percent.cc modules/pandora_module_logevent.cc modules/pandora_module_service.cc modules/pandora_module_cpuusage.cc modules/pandora_module_wmiquery.cc modules/pandora_module_regexp.cc modules/pandora_module_ping.cc modules/pandora_module_snmpget.cc udp_server/udp_server.cc main.cc pandora_strutils.cc pandora.cc windows_service.cc pandora_agent_conf.cc windows/pandora_windows_info.cc windows/pandora_wmi.cc pandora_windows_service.cc misc/md5.c misc/sha256.cc windows/wmi/disphelper.c ssh/libssh2/channel.c ssh/libssh2/mac.c ssh/libssh2/session.c ssh/libssh2/comp.c ssh/libssh2/misc.c ssh/libssh2/sftp.c ssh/libssh2/crypt.c ssh/libssh2/packet.c ssh/libssh2/userauth.c ssh/libssh2/hostkey.c ssh/libssh2/publickey.c ssh/libssh2/kex.c ssh/libssh2/scp.c ssh/pandora_ssh_client.cc ssh/pandora_ssh_test.cc ftp/pandora_ftp_client.cc ftp/pandora_ftp_test.cc debug_new.cpp
|
||||
PandoraAgent_CXXFLAGS=-g -O0
|
||||
else
|
||||
PandoraAgent_SOURCES = misc/pandora_file.cc modules/pandora_data.cc modules/pandora_module_factory.cc modules/pandora_module.cc modules/pandora_module_list.cc modules/pandora_module_plugin.cc modules/pandora_module_inventory.cc modules/pandora_module_freememory.cc modules/pandora_module_exec.cc modules/pandora_module_perfcounter.cc modules/pandora_module_proc.cc modules/pandora_module_tcpcheck.cc modules/pandora_module_freememory_percent.cc modules/pandora_module_freedisk.cc modules/pandora_module_freedisk_percent.cc modules/pandora_module_logevent.cc modules/pandora_module_service.cc modules/pandora_module_cpuusage.cc modules/pandora_module_wmiquery.cc modules/pandora_module_regexp.cc modules/pandora_module_ping.cc modules/pandora_module_snmpget.cc udp_server/udp_server.cc main.cc pandora_strutils.cc pandora.cc windows_service.cc pandora_agent_conf.cc windows/pandora_windows_info.cc windows/pandora_wmi.cc pandora_windows_service.cc misc/md5.c misc/sha256.cc windows/wmi/disphelper.c ssh/libssh2/channel.c ssh/libssh2/mac.c ssh/libssh2/session.c ssh/libssh2/comp.c ssh/libssh2/misc.c ssh/libssh2/sftp.c ssh/libssh2/crypt.c ssh/libssh2/packet.c ssh/libssh2/userauth.c ssh/libssh2/hostkey.c ssh/libssh2/publickey.c ssh/libssh2/kex.c ssh/libssh2/scp.c ssh/pandora_ssh_client.cc ssh/pandora_ssh_test.cc ftp/pandora_ftp_client.cc ftp/pandora_ftp_test.cc
|
||||
PandoraAgent_SOURCES = misc/pandora_file.cc modules/pandora_data.cc modules/pandora_module_factory.cc modules/pandora_module.cc modules/pandora_module_list.cc modules/pandora_module_plugin.cc modules/pandora_module_inventory.cc modules/pandora_module_freememory.cc modules/pandora_module_exec.cc modules/pandora_module_perfcounter.cc modules/pandora_module_proc.cc modules/pandora_module_tcpcheck.cc modules/pandora_module_freememory_percent.cc modules/pandora_module_freedisk.cc modules/pandora_module_freedisk_percent.cc modules/pandora_module_logevent.cc modules/pandora_module_logchannel.cc modules/pandora_module_service.cc modules/pandora_module_cpuusage.cc modules/pandora_module_wmiquery.cc modules/pandora_module_regexp.cc modules/pandora_module_ping.cc modules/pandora_module_snmpget.cc udp_server/udp_server.cc main.cc pandora_strutils.cc pandora.cc windows_service.cc pandora_agent_conf.cc windows/pandora_windows_info.cc windows/pandora_wmi.cc pandora_windows_service.cc misc/md5.c misc/sha256.cc windows/wmi/disphelper.c ssh/libssh2/channel.c ssh/libssh2/mac.c ssh/libssh2/session.c ssh/libssh2/comp.c ssh/libssh2/misc.c ssh/libssh2/sftp.c ssh/libssh2/crypt.c ssh/libssh2/packet.c ssh/libssh2/userauth.c ssh/libssh2/hostkey.c ssh/libssh2/publickey.c ssh/libssh2/kex.c ssh/libssh2/scp.c ssh/pandora_ssh_client.cc ssh/pandora_ssh_test.cc ftp/pandora_ftp_client.cc ftp/pandora_ftp_test.cc
|
||||
PandoraAgent_CXXFLAGS=-O2
|
||||
endif
|
||||
|
||||
|
@ -248,7 +248,9 @@ Pandora_Module::parseModuleKindFromString (string kind) {
|
||||
} else if (kind == module_inventory_str) {
|
||||
return MODULE_INVENTORY;
|
||||
} else if (kind == module_logevent_str) {
|
||||
return MODULE_LOGEVENT;
|
||||
return MODULE_LOGEVENT;
|
||||
} else if (kind == module_logchannel_str) {
|
||||
return MODULE_LOGCHANNEL;
|
||||
} else if (kind == module_wmiquery_str) {
|
||||
return MODULE_WMIQUERY;
|
||||
} else if (kind == module_perfcounter_str) {
|
||||
|
@ -86,6 +86,7 @@ namespace Pandora_Modules {
|
||||
MODULE_FREEMEMORY_PERCENT, /**< The module checks the amount of
|
||||
* freememory in the system */
|
||||
MODULE_LOGEVENT, /**< The module checks for log events */
|
||||
MODULE_LOGCHANNEL, /**< The module checks for log events on channel using XML functions*/
|
||||
MODULE_WMIQUERY, /**< The module runs WQL queries */
|
||||
MODULE_PERFCOUNTER, /**< The module reads performance counters */
|
||||
MODULE_TCPCHECK, /**< The module checks whether a tcp port is open */
|
||||
@ -126,6 +127,7 @@ namespace Pandora_Modules {
|
||||
const string module_cpuusage_str = "module_cpuusage";
|
||||
const string module_inventory_str = "module_inventory";
|
||||
const string module_logevent_str = "module_logevent";
|
||||
const string module_logchannel_str = "module_logchannel";
|
||||
const string module_wmiquery_str = "module_wmiquery";
|
||||
const string module_perfcounter_str = "module_perfcounter";
|
||||
const string module_tcpcheck_str = "module_tcpcheck";
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "pandora_module_cpuusage.h"
|
||||
#include "pandora_module_inventory.h"
|
||||
#include "pandora_module_logevent.h"
|
||||
#include "pandora_module_logchannel.h"
|
||||
#include "pandora_module_wmiquery.h"
|
||||
#include "pandora_module_perfcounter.h"
|
||||
#include "pandora_module_tcpcheck.h"
|
||||
@ -69,6 +70,7 @@ using namespace Pandora_Strutils;
|
||||
#define TOKEN_MIN_FF_EVENT ("module_min_ff_event ")
|
||||
#define TOKEN_DESCRIPTION ("module_description ")
|
||||
#define TOKEN_LOGEVENT ("module_logevent")
|
||||
#define TOKEN_LOGCHANNEL ("module_logchannel")
|
||||
#define TOKEN_SOURCE ("module_source ")
|
||||
#define TOKEN_EVENTTYPE ("module_eventtype ")
|
||||
#define TOKEN_EVENTCODE ("module_eventcode ")
|
||||
@ -157,6 +159,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||
string module_freedisk_percent, module_freememory_percent;
|
||||
string module_dsn, module_freememory;
|
||||
string module_logevent, module_source, module_eventtype, module_eventcode;
|
||||
string module_logchannel;
|
||||
string module_pattern, module_application, module_async;
|
||||
string module_watchdog, module_start_command;
|
||||
string module_wmiquery, module_wmicolumn;
|
||||
@ -195,6 +198,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||
module_proc = "";
|
||||
module_service = "";
|
||||
module_logevent = "";
|
||||
module_logchannel = "";
|
||||
module_source = "";
|
||||
module_eventtype = "";
|
||||
module_eventcode = "";
|
||||
@ -342,6 +346,9 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||
if (module_logevent == "") {
|
||||
module_logevent = parseLine (line, TOKEN_LOGEVENT);
|
||||
}
|
||||
if (module_logchannel == "") {
|
||||
module_logchannel = parseLine (line, TOKEN_LOGCHANNEL);
|
||||
}
|
||||
if (module_source == "") {
|
||||
module_source = parseLine (line, TOKEN_SOURCE);
|
||||
}
|
||||
@ -724,6 +731,13 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||
}
|
||||
}
|
||||
|
||||
if (module_logchannel != "") {
|
||||
pos_macro = module_logchannel.find(macro_name);
|
||||
if (pos_macro != string::npos){
|
||||
module_logchannel.replace(pos_macro, macro_name.size(), macro_value);
|
||||
}
|
||||
}
|
||||
|
||||
if (module_source != "") {
|
||||
pos_macro = module_source.find(macro_name);
|
||||
if (pos_macro != string::npos){
|
||||
@ -1173,6 +1187,13 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||
module_eventcode,
|
||||
module_pattern,
|
||||
module_application);
|
||||
}
|
||||
else if (module_logchannel != "") {
|
||||
module = new Pandora_Module_Logchannel (module_name,
|
||||
module_source,
|
||||
module_eventtype,
|
||||
module_eventcode,
|
||||
module_pattern);
|
||||
} else if (module_wmiquery != "") {
|
||||
module = new Pandora_Module_WMIQuery (module_name,
|
||||
module_wmiquery, module_wmicolumn);
|
||||
|
@ -30,12 +30,13 @@
|
||||
#include "pandora_module_cpuusage.h"
|
||||
#include "pandora_module_inventory.h"
|
||||
#include "pandora_module_logevent.h"
|
||||
#include "pandora_module_logchannel.h"
|
||||
#include "pandora_module_wmiquery.h"
|
||||
#include "pandora_module_perfcounter.h"
|
||||
#include "pandora_module_tcpcheck.h"
|
||||
#include "pandora_module_regexp.h"
|
||||
#include "pandora_module_plugin.h"
|
||||
#include "pandora_module_ping.h"
|
||||
#include "pandora_module_ping.h"
|
||||
#include "pandora_module_snmpget.h"
|
||||
#include <fstream>
|
||||
|
||||
@ -226,12 +227,13 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition)
|
||||
Pandora_Module_Freememory *module_freememory;
|
||||
Pandora_Module_Freememory_Percent *module_freememory_percent;
|
||||
Pandora_Module_Logevent *module_logevent;
|
||||
Pandora_Module_Logchannel *module_logchannel;
|
||||
Pandora_Module_WMIQuery *module_wmiquery;
|
||||
Pandora_Module_Perfcounter *module_perfcounter;
|
||||
Pandora_Module_Tcpcheck *module_tcpcheck;
|
||||
Pandora_Module_Regexp *module_regexp;
|
||||
Pandora_Module_Plugin *module_plugin;
|
||||
Pandora_Module_Ping *module_ping;
|
||||
Pandora_Module_Ping *module_ping;
|
||||
Pandora_Module_SNMPGet *module_snmpget;
|
||||
|
||||
module = Pandora_Module_Factory::getModuleFromDefinition (definition);
|
||||
@ -288,6 +290,10 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition)
|
||||
module_logevent = (Pandora_Module_Logevent *) module;
|
||||
modules->push_back (module_logevent);
|
||||
break;
|
||||
case MODULE_LOGCHANNEL:
|
||||
module_logchannel = (Pandora_Module_Logchannel *) module;
|
||||
modules->push_back (module_logchannel);
|
||||
break;
|
||||
case MODULE_WMIQUERY:
|
||||
module_wmiquery = (Pandora_Module_WMIQuery *) module;
|
||||
modules->push_back (module_wmiquery);
|
||||
@ -315,7 +321,7 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition)
|
||||
case MODULE_SNMPGET:
|
||||
module_snmpget = (Pandora_Module_SNMPGet *) module;
|
||||
modules->push_back (module_snmpget);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
582
pandora_agents/win32/modules/pandora_module_logchannel.cc
Executable file
582
pandora_agents/win32/modules/pandora_module_logchannel.cc
Executable file
@ -0,0 +1,582 @@
|
||||
/* Pandora logchannel module. This module checks for log events that match a given
|
||||
pattern using XML functions provided by wevtapi.
|
||||
|
||||
Copyright (C) 2017 Artica ST.
|
||||
Written by Fermin Hernandez.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <time.h>
|
||||
|
||||
#include "pandora_module_logchannel.h"
|
||||
#include "../windows/pandora_wmi.h"
|
||||
#include "../pandora_windows_service.h"
|
||||
#include "pandora_module_logchannel.h"
|
||||
#include "pandora_strutils.h"
|
||||
|
||||
using namespace Pandora;
|
||||
using namespace Pandora_Modules;
|
||||
using namespace Pandora_Strutils;
|
||||
|
||||
// Pointers to Wevtapi.dll functions
|
||||
static HINSTANCE WINEVENT = NULL;
|
||||
static EvtQueryT EvtQueryF = NULL;
|
||||
static EvtNextT EvtNextF = NULL;
|
||||
static EvtSeekT EvtSeekF = NULL;
|
||||
static EvtCreateRenderContextT EvtCreateRenderContextF = NULL;
|
||||
static EvtRenderT EvtRenderF = NULL;
|
||||
static EvtCloseT EvtCloseF = NULL;
|
||||
static EvtFormatMessageT EvtFormatMessageF = NULL;
|
||||
static EvtOpenPublisherMetadataT EvtOpenPublisherMetadataF = NULL;
|
||||
static EvtCreateBookmarkT EvtCreateBookmarkF = NULL;
|
||||
static EvtUpdateBookmarkT EvtUpdateBookmarkF = NULL;
|
||||
|
||||
/**
|
||||
* Creates a Pandora_Module_Logchannel object.
|
||||
*
|
||||
* @param name Module name.
|
||||
* @param service_name Service internal name to check.
|
||||
*/
|
||||
Pandora_Module_Logchannel::Pandora_Module_Logchannel (string name, string source, string type, string id, string pattern)
|
||||
: Pandora_Module (name) {
|
||||
int i;
|
||||
vector<wstring> query;
|
||||
vector<wstring>::iterator query_it;
|
||||
string upper_type = type;
|
||||
|
||||
// Convert the type string to uppercase
|
||||
for (i = 0; i < type.length(); i++) {
|
||||
upper_type[i] = toupper(type[i]);
|
||||
}
|
||||
|
||||
// Set the type filter
|
||||
int type_number = -1;
|
||||
if (upper_type.compare("ERROR") == 0) {
|
||||
type_number = EVENTLOG_ERROR_TYPE;
|
||||
} else if (upper_type.compare("WARNING") == 0) {
|
||||
type_number = EVENTLOG_WARNING_TYPE;
|
||||
} else if (upper_type.compare("INFORMATION") == 0) {
|
||||
type_number = EVENTLOG_INFORMATION_TYPE;
|
||||
} else if (upper_type.compare("AUDIT SUCCESS") == 0) {
|
||||
type_number = EVENTLOG_AUDIT_SUCCESS;
|
||||
} else if (upper_type.compare("AUDIT FAILURE") == 0) {
|
||||
type_number = EVENTLOG_AUDIT_FAILURE;
|
||||
}
|
||||
// Append type to log query
|
||||
if (type_number != -1) {
|
||||
wstringstream ss;
|
||||
ss << L"*[System[Level='" << type_number << L"']]";
|
||||
query.push_back(ss.str());
|
||||
}
|
||||
|
||||
// Set the id
|
||||
int id_number = strtoul (id.c_str (), NULL, 0);
|
||||
if (id_number != 0) {
|
||||
wstringstream ss;
|
||||
ss << L"*[System[EventID='" << id_number << L"']]";
|
||||
query.push_back(ss.str());
|
||||
}
|
||||
|
||||
// Fill the filter
|
||||
if (query.size() == 0) {
|
||||
this->filter = L"*";
|
||||
} else {
|
||||
int i = 0;
|
||||
// Add filters with and
|
||||
wstring item_query;
|
||||
while (query.size() > 1) {
|
||||
item_query = query.back();
|
||||
query.pop_back();
|
||||
this->filter += item_query + L" and ";
|
||||
}
|
||||
// Append the last value without the and
|
||||
item_query = query.back();
|
||||
this->filter += item_query;
|
||||
}
|
||||
|
||||
this->source = source;
|
||||
this->pattern = pattern;
|
||||
if (! pattern.empty ()) {
|
||||
// Compile the regular expression
|
||||
if (regcomp (&this->regexp, pattern.c_str (), REG_EXTENDED) != 0) {
|
||||
pandoraLog ("Invalid regular expression %s", pattern.c_str ());
|
||||
}
|
||||
}
|
||||
this->bookmark_xml = L"";
|
||||
this->setKind (module_logchannel_str);
|
||||
|
||||
// Load Wevtapi.dll and some functions
|
||||
if (WINEVENT == NULL) {
|
||||
WINEVENT = LoadLibrary("Wevtapi.dll");
|
||||
if (WINEVENT == NULL) {
|
||||
|
||||
// Log to the bedug log, since this is not an error
|
||||
pandoraLog ("Library Wevtapi.dll not available");
|
||||
return;
|
||||
}
|
||||
|
||||
EvtQueryF = (EvtQueryT) GetProcAddress (WINEVENT, "EvtQuery");
|
||||
if (EvtQueryF == NULL) {
|
||||
pandoraLog ("Error loading function EvtQuery from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtNextF = (EvtNextT) GetProcAddress (WINEVENT, "EvtNext");
|
||||
if (EvtNextF == NULL) {
|
||||
pandoraLog ("Error loading function EvtNext from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtSeekF = (EvtSeekT) GetProcAddress (WINEVENT, "EvtSeek");
|
||||
if (EvtSeekF == NULL) {
|
||||
pandoraLog ("Error loading function EvtSeek from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtCreateRenderContextF = (EvtCreateRenderContextT) GetProcAddress (WINEVENT, "EvtCreateRenderContext");
|
||||
if (EvtCreateRenderContextF == NULL) {
|
||||
pandoraLog ("Error loading function EvtCreateRenderContext from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtRenderF = (EvtRenderT) GetProcAddress (WINEVENT, "EvtRender");
|
||||
if (EvtRenderF == NULL) {
|
||||
pandoraLog ("Error loading function EvtRender from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtCloseF = (EvtCloseT) GetProcAddress (WINEVENT, "EvtClose");
|
||||
if (EvtCloseF == NULL) {
|
||||
pandoraLog ("Error loading function EvtClose from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtFormatMessageF = (EvtFormatMessageT) GetProcAddress (WINEVENT, "EvtFormatMessage");
|
||||
if (EvtFormatMessageF == NULL) {
|
||||
pandoraLog ("Error loading function EvtFormatMessage from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtOpenPublisherMetadataF = (EvtOpenPublisherMetadataT) GetProcAddress (WINEVENT, "EvtOpenPublisherMetadata");
|
||||
if (EvtOpenPublisherMetadataF == NULL) {
|
||||
pandoraLog ("Error loading function EvtOpenPublisherMetadata from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtCreateBookmarkF = (EvtCreateBookmarkT) GetProcAddress (WINEVENT, "EvtCreateBookmark");
|
||||
if (EvtCreateBookmarkF == NULL) {
|
||||
pandoraLog ("Error loading function EvtCreateBookmark from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
EvtUpdateBookmarkF = (EvtUpdateBookmarkT) GetProcAddress (WINEVENT, "EvtUpdateBookmark");
|
||||
if (EvtUpdateBookmarkF == NULL) {
|
||||
pandoraLog ("Error loading function EvtUpdateBookmark from Wevtapi.dll");
|
||||
FreeLibrary (WINEVENT);
|
||||
WINEVENT = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Pandora_Module_Logchannel::run () {
|
||||
list<LogChannelList> event_list;
|
||||
list<LogChannelList>::iterator event;
|
||||
SYSTEMTIME system_time;
|
||||
|
||||
// Run
|
||||
try {
|
||||
Pandora_Module::run ();
|
||||
} catch (Interval_Not_Fulfilled e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize log event query
|
||||
this->initializeLogChannel();
|
||||
|
||||
// Read events on a list
|
||||
this->getLogEvents (event_list);
|
||||
|
||||
// Return if no data stored on list
|
||||
if (event_list.size () < 1) return;
|
||||
|
||||
for (event = event_list.begin (); event != event_list.end(); ++event) {
|
||||
// Store the data
|
||||
this->setOutput (event->message, &(event->timestamp));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the first bookmark of events.
|
||||
*/
|
||||
void
|
||||
Pandora_Module_Logchannel::initializeLogChannel () {
|
||||
EVT_HANDLE hEvents[1];
|
||||
EVT_HANDLE hResults;
|
||||
EVT_HANDLE hBookmark;
|
||||
DWORD dwReturned = 0;
|
||||
|
||||
// Check whether the first bookmark is set
|
||||
if (!this->bookmark_xml.empty()) return;
|
||||
|
||||
// Open the event log with a query
|
||||
hResults = EvtQueryF (
|
||||
NULL,
|
||||
strAnsiToUnicode (this->source.c_str()).c_str(),
|
||||
this->filter.c_str(),
|
||||
EvtOpenChannelPath | EvtQueryForwardDirection
|
||||
);
|
||||
if (hResults == NULL) {
|
||||
pandoraDebug ("Could not open event log channel. Error: '%d'", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
// Put the events on the last event
|
||||
if (!EvtSeekF(hResults, 0, NULL, 0, EvtSeekRelativeToLast)) {
|
||||
pandoraDebug("Cannot positionate the event at first. 'Error %d'.", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
return;
|
||||
}
|
||||
// Read next event to positionate the bookmark
|
||||
if (!EvtNextF(hResults, 1, hEvents, INFINITE, 0, &dwReturned)) {
|
||||
if (GetLastError() != ERROR_NO_MORE_ITEMS) {
|
||||
pandoraDebug ("EvtNext (initializeLogChannel) error: %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If no events read, do not use bookmark to read all events
|
||||
if (dwReturned == 0) {
|
||||
pandoraDebug("No events found positionating bookmark.");
|
||||
EvtCloseF(hResults);
|
||||
return;
|
||||
}
|
||||
// Create the bookmar
|
||||
pandoraDebug("Creating bookmark to channel %s", this->source.c_str());
|
||||
hBookmark = EvtCreateBookmarkF(NULL);
|
||||
if (hBookmark == NULL) {
|
||||
pandoraDebug("EvtCreateBookmark (initializeLogChannel) failed %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hEvents[0]);
|
||||
return;
|
||||
}
|
||||
if (!EvtUpdateBookmarkF(hBookmark, hEvents[0])) {
|
||||
pandoraDebug("EvtUpdateBookmarkF (initializeLogChannel) failed %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hEvents[0]);
|
||||
EvtCloseF(hBookmark);
|
||||
return;
|
||||
}
|
||||
// Save the bookmark like an XML.
|
||||
this->updateBookmarkXML(hBookmark);
|
||||
|
||||
// Clean tasks
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the bookmark XML. Returns false if fails
|
||||
*/
|
||||
bool
|
||||
Pandora_Module_Logchannel::updateBookmarkXML (EVT_HANDLE hBookmark) {
|
||||
LPWSTR pBookmarkXml = NULL;
|
||||
DWORD dwBufferSize = 0;
|
||||
DWORD dwBufferUsed = 0;
|
||||
DWORD dwPropertyCount = 0;
|
||||
DWORD status = 0;
|
||||
|
||||
if (!EvtRenderF(NULL, hBookmark, EvtRenderBookmark, dwBufferSize, pBookmarkXml, &dwBufferUsed, &dwPropertyCount)){
|
||||
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError())){
|
||||
dwBufferSize = dwBufferUsed;
|
||||
pBookmarkXml = (LPWSTR)malloc(dwBufferSize);
|
||||
if (pBookmarkXml){
|
||||
EvtRenderF(NULL, hBookmark, EvtRenderBookmark, dwBufferSize, pBookmarkXml, &dwBufferUsed, &dwPropertyCount);
|
||||
}
|
||||
else{
|
||||
pandoraDebug("Error loading the bookmark. Cannot load enough memory");
|
||||
this->cleanBookmark();
|
||||
free(pBookmarkXml);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (ERROR_SUCCESS != (status = GetLastError())){
|
||||
pandoraDebug("EvtRender (updateBookmarkXML) failed with %d\n", GetLastError());
|
||||
this->cleanBookmark();
|
||||
free(pBookmarkXml);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this->bookmark_xml = pBookmarkXml;
|
||||
free(pBookmarkXml);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the bookmark XML.
|
||||
*/
|
||||
void
|
||||
Pandora_Module_Logchannel::cleanBookmark () {
|
||||
this->bookmark_xml = L"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads available events from the event log.
|
||||
*/
|
||||
void
|
||||
Pandora_Module_Logchannel::getLogEvents (list<LogChannelList> &event_list) {
|
||||
EVT_HANDLE hResults = NULL;
|
||||
EVT_HANDLE hBookmark = NULL;
|
||||
EVT_HANDLE hEvents[1];
|
||||
EVT_HANDLE hContext = NULL;
|
||||
PEVT_VARIANT pRenderedValues = NULL;
|
||||
EVT_HANDLE hProviderMetadata = NULL;
|
||||
LPWSTR pwsMessage = NULL;
|
||||
LPWSTR ppValues[] = {L"Event/System/Provider/@Name", L"Event/System/TimeCreated/@SystemTime"};
|
||||
DWORD count = sizeof(ppValues)/sizeof(LPWSTR);
|
||||
DWORD dwReturned = 0;
|
||||
DWORD dwBufferSize = 0;
|
||||
DWORD dwBufferUsed = 0;
|
||||
DWORD dwPropertyCount = 0;
|
||||
DWORD status = ERROR_SUCCESS;
|
||||
SYSTEMTIME eventTime;
|
||||
FILETIME lft, ft;
|
||||
bool update_bookmark = false;
|
||||
|
||||
// An empty bookmark XML means that log cannot be open
|
||||
if (this->bookmark_xml.empty()) return;
|
||||
|
||||
// Open the event log with a query
|
||||
hResults = EvtQueryF (
|
||||
NULL,
|
||||
strAnsiToUnicode (this->source.c_str()).c_str(),
|
||||
this->filter.c_str(),
|
||||
EvtOpenChannelPath | EvtQueryForwardDirection
|
||||
);
|
||||
if (hResults == NULL) {
|
||||
pandoraDebug ("Could not open event log channel '%s'. Error: '%d'", this->source.c_str(), GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Seek on the bookmark
|
||||
hBookmark = EvtCreateBookmarkF(this->bookmark_xml.c_str());
|
||||
if (hBookmark == NULL) {
|
||||
pandoraDebug("Cannot read the string bookmark. Error: %d.", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
if (!EvtSeekF(hResults, 1, hBookmark, 0, EvtSeekRelativeToBookmark)) {
|
||||
pandoraDebug("Cannot positionate the event at bookmark. Error %d.", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Read events one by one
|
||||
hEvents[0] = NULL;
|
||||
while (EvtNextF(hResults, 1, hEvents, INFINITE, 0, &dwReturned)) {
|
||||
hContext = EvtCreateRenderContextF(count, (LPCWSTR*)ppValues, EvtRenderContextValues);
|
||||
if (NULL == hContext) {
|
||||
pandoraDebug ("EvtCreateRenderContext error: %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Reinitialize the buffers
|
||||
dwBufferSize = 0;
|
||||
dwBufferUsed = 0;
|
||||
if (! EvtRenderF(hContext, hEvents[0], EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount)) {
|
||||
if ((status = GetLastError()) == ERROR_INSUFFICIENT_BUFFER) {
|
||||
dwBufferSize = dwBufferUsed;
|
||||
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
|
||||
if (pRenderedValues) {
|
||||
EvtRenderF(hContext, hEvents[0], EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
|
||||
}
|
||||
else {
|
||||
pandoraDebug ("EvtRender error: %d", status);
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
EvtCloseF(hContext);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((status = GetLastError()) != ERROR_SUCCESS) {
|
||||
pandoraDebug ("EvtRender error getting buffer size: %d", status);
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
EvtCloseF(hContext);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the SYSTEMTIME of log
|
||||
ULONGLONG ullTimeStamp = pRenderedValues[1].FileTimeVal;
|
||||
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
|
||||
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
|
||||
// Time format conversions
|
||||
if (!FileTimeToLocalFileTime(&ft, &lft)){
|
||||
pandoraDebug("UTC FILETIME to LOCAL FILETIME error: %d.", GetLastError());
|
||||
} else if (!FileTimeToSystemTime(&lft, &eventTime)){
|
||||
pandoraDebug("FILETIME to SYSTEMTIME error: %d.", GetLastError());
|
||||
}
|
||||
|
||||
// Get the handle to the provider's metadata that contains the message strings
|
||||
hProviderMetadata = EvtOpenPublisherMetadataF(NULL, pRenderedValues[0].StringVal, NULL, 0, 0);
|
||||
if (hProviderMetadata == NULL) {
|
||||
pandoraDebug ("EvtOpenPublisherMetadata error: %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
EvtCloseF(hContext);
|
||||
free(pRenderedValues);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the event message
|
||||
pwsMessage = GetMessageString(hProviderMetadata, hEvents[0], EvtFormatMessageEvent);
|
||||
if (pwsMessage == NULL) {
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
EvtCloseF(hContext);
|
||||
free(pRenderedValues);
|
||||
EvtCloseF(hProviderMetadata);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the regex and save the message if pass the regex
|
||||
if (this->pattern.empty () || regexec (&this->regexp, strUnicodeToAnsi(pwsMessage).c_str (), 0, NULL, 0) == 0){
|
||||
// Save the event message
|
||||
LogChannelList event_item;
|
||||
event_item.message = strUnicodeToAnsi(pwsMessage);
|
||||
event_item.timestamp= eventTime;
|
||||
event_list.push_back (event_item);
|
||||
}
|
||||
|
||||
// Clean up some used vars
|
||||
EvtCloseF(hContext);
|
||||
free(pRenderedValues);
|
||||
EvtCloseF(hProviderMetadata);
|
||||
free(pwsMessage);
|
||||
|
||||
// Update the bookmark
|
||||
if (!EvtUpdateBookmarkF(hBookmark, hEvents[0])) {
|
||||
pandoraDebug("EvtUpdateBookmarkF (getLogEvents) failed %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
EvtCloseF(hEvents[0]);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Cleanup current event and read the next log
|
||||
EvtCloseF(hEvents[0]);
|
||||
hEvents[0] = NULL;
|
||||
|
||||
// Information token to update bookmark
|
||||
update_bookmark = true;
|
||||
}
|
||||
status = GetLastError();
|
||||
if (status != ERROR_NO_MORE_ITEMS) {
|
||||
pandoraDebug ("EvtNext getLogEvents error: %d", GetLastError());
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
this->cleanBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
// Update bookmark if there is new events
|
||||
if (update_bookmark) this->updateBookmarkXML(hBookmark);
|
||||
|
||||
// Clean handlers
|
||||
EvtCloseF(hResults);
|
||||
EvtCloseF(hBookmark);
|
||||
}
|
||||
|
||||
// Gets the specified message string from the event. If the event does not
|
||||
// contain the specified message, the function returns NULL.
|
||||
// See http://msdn.microsoft.com/en-us/library/windows/desktop/dd996923(v=vs.85).aspx
|
||||
LPWSTR
|
||||
Pandora_Module_Logchannel::GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId) {
|
||||
LPWSTR pBuffer = NULL;
|
||||
DWORD dwBufferSize = 0;
|
||||
DWORD dwBufferUsed = 0;
|
||||
DWORD status = 0;
|
||||
|
||||
if (!EvtFormatMessageF(hMetadata, hEvent, 0, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed)) {
|
||||
status = GetLastError();
|
||||
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
||||
// An event can contain one or more keywords. The function returns keywords
|
||||
// as a list of keyword strings. To process the list, you need to know the
|
||||
// size of the buffer, so you know when you have read the last string, or you
|
||||
// can terminate the list of strings with a second null terminator character
|
||||
// as this example does.
|
||||
if ((EvtFormatMessageKeyword == FormatId)) {
|
||||
pBuffer[dwBufferSize-1] = L'\0';
|
||||
}
|
||||
else {
|
||||
dwBufferSize = dwBufferUsed;
|
||||
}
|
||||
pBuffer = (LPWSTR)malloc(dwBufferSize * sizeof(WCHAR));
|
||||
|
||||
if (pBuffer) {
|
||||
EvtFormatMessageF(hMetadata, hEvent, 0, 0, NULL, FormatId, dwBufferSize, pBuffer, &dwBufferUsed);
|
||||
|
||||
// Add the second null terminator character.
|
||||
if ((EvtFormatMessageKeyword == FormatId)) {
|
||||
pBuffer[dwBufferUsed-1] = L'\0';
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pandoraDebug ("EvtFormatMessage error: %d", status);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pBuffer;
|
||||
}
|
76
pandora_agents/win32/modules/pandora_module_logchannel.h
Executable file
76
pandora_agents/win32/modules/pandora_module_logchannel.h
Executable file
@ -0,0 +1,76 @@
|
||||
/* Pandora logchannel module. This module checks for log events that match a given
|
||||
pattern using XML functions provided by wevtapi.
|
||||
|
||||
Copyright (C) 2017 Artica ST.
|
||||
Written by Fermin Hernandez.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PANDORA_MODULE_LOGCHANNEL_H__
|
||||
#define __PANDORA_MODULE_LOGCHANNEL_H__
|
||||
|
||||
#include "pandora_module.h"
|
||||
#include "boost/regex.h"
|
||||
#include "../windows/winevt.h"
|
||||
|
||||
// Log event read buffer size
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
// Types for pointers to Wevtapi.dll functions
|
||||
typedef EVT_HANDLE WINAPI (*EvtQueryT) (EVT_HANDLE Session, LPCWSTR Path, LPCWSTR Query, DWORD Flags);
|
||||
typedef WINBOOL WINAPI (*EvtNextT) (EVT_HANDLE ResultSet, DWORD EventArraySize, EVT_HANDLE* EventArray, DWORD Timeout, DWORD Flags, PDWORD Returned);
|
||||
typedef WINBOOL WINAPI (*EvtSeekT) (EVT_HANDLE ResultSet, LONGLONG Position, EVT_HANDLE Bookmark, DWORD Timeout, DWORD Flags);
|
||||
typedef EVT_HANDLE WINAPI (*EvtCreateRenderContextT) (DWORD ValuePathsCount, LPCWSTR *ValuePaths, DWORD Flags);
|
||||
typedef WINBOOL WINAPI (*EvtRenderT) (EVT_HANDLE Context, EVT_HANDLE Fragment, DWORD Flags, DWORD BufferSize, PVOID Buffer, PDWORD BufferUsed, PDWORD PropertyCount);
|
||||
typedef WINBOOL WINAPI (*EvtCloseT) (EVT_HANDLE Object);
|
||||
typedef WINBOOL WINAPI (*EvtFormatMessageT) (EVT_HANDLE PublisherMetadata, EVT_HANDLE Event, DWORD MessageId, DWORD ValueCount, PEVT_VARIANT Values, DWORD Flags, DWORD BufferSize, LPWSTR Buffer, PDWORD BufferUsed);
|
||||
typedef EVT_HANDLE WINAPI (*EvtOpenPublisherMetadataT) (EVT_HANDLE Session, LPCWSTR PublisherIdentity, LPCWSTR LogFilePath, LCID Locale, DWORD Flags);
|
||||
typedef EVT_HANDLE WINAPI (*EvtCreateBookmarkT) (LPCWSTR BookmarkXml);
|
||||
typedef WINBOOL WINAPI (*EvtUpdateBookmarkT) (EVT_HANDLE Bookmark, EVT_HANDLE Event);
|
||||
|
||||
namespace Pandora_Modules {
|
||||
|
||||
/**
|
||||
* This module checks for log events that match a given
|
||||
* pattern. Events can be filtered by source and type.
|
||||
*/
|
||||
|
||||
class Pandora_Module_Logchannel : public Pandora_Module {
|
||||
struct LogChannelList {
|
||||
string message;
|
||||
SYSTEMTIME timestamp;
|
||||
};
|
||||
private:
|
||||
regex_t regexp;
|
||||
string source;
|
||||
string pattern;
|
||||
wstring filter;
|
||||
wstring bookmark_xml;
|
||||
HANDLE messages_dll;
|
||||
|
||||
void initializeLogChannel ();
|
||||
bool updateBookmarkXML (EVT_HANDLE hBookmark);
|
||||
void getLogEvents (list<LogChannelList> &event_list);
|
||||
void cleanBookmark ();
|
||||
LPWSTR GetMessageString(EVT_HANDLE hMetadata, EVT_HANDLE hEvent, EVT_FORMAT_MESSAGE_FLAGS FormatId);
|
||||
|
||||
public:
|
||||
Pandora_Module_Logchannel (string name, string source, string type, string id, string pattern);
|
||||
void run ();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user