Skip to content

Commit

Permalink
in_winevtlog: Support XML query parameter for filtering events
Browse files Browse the repository at this point in the history
Signed-off-by: Hiroshi Hatake <[email protected]>
  • Loading branch information
cosmo0920 authored and edsiper committed Aug 29, 2023
1 parent b23f8d8 commit 5c19f46
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
8 changes: 6 additions & 2 deletions plugins/in_winevtlog/in_winevtlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ static int in_winevtlog_init(struct flb_input_instance *in,
tmp = "Application";
}

ctx->active_channel = winevtlog_open_all(tmp, ctx->read_existing_events, ctx->ignore_missing_channels);
ctx->active_channel = winevtlog_open_all(tmp, ctx);
if (!ctx->active_channel) {
flb_plg_error(ctx->ins, "failed to open channels");
flb_log_event_encoder_destroy(ctx->log_encoder);
Expand Down Expand Up @@ -256,7 +256,11 @@ static struct flb_config_map config_map[] = {
0, FLB_TRUE, offsetof(struct winevtlog_config, ignore_missing_channels),
"Whether to ignore channels missing in eventlog"
},

{
FLB_CONFIG_MAP_STR, "event_query", "*",
0, FLB_TRUE, offsetof(struct winevtlog_config, event_query),
"Specify XML query for filtering events"
},
/* EOF */
{0}
};
Expand Down
37 changes: 30 additions & 7 deletions plugins/in_winevtlog/winevtlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ static char* convert_wstr(wchar_t *wstr, UINT codePage);
static wchar_t* convert_str(char *str);

struct winevtlog_channel *winevtlog_subscribe(const char *channel, int read_existing_events,
EVT_HANDLE stored_bookmark)
EVT_HANDLE stored_bookmark, const char *query)
{
struct winevtlog_channel *ch;
EVT_HANDLE bookmark = NULL;
HANDLE signal_event = NULL;
DWORD len;
DWORD flags = 0L;
PWSTR wide_channel = L"Application";
PWSTR wide_query = L"*";
PWSTR wide_channel = NULL;
PWSTR wide_query = NULL;
void *buf;

ch = flb_calloc(1, sizeof(struct winevtlog_channel));
Expand All @@ -54,13 +54,21 @@ struct winevtlog_channel *winevtlog_subscribe(const char *channel, int read_exis
flb_free(ch);
return NULL;
}
ch->query = NULL;

signal_event = CreateEvent(NULL, FALSE, FALSE, NULL);

// channel : To wide char
len = MultiByteToWideChar(CP_UTF8, 0, channel, -1, NULL, 0);
wide_channel = flb_malloc(sizeof(PWSTR) * len);
MultiByteToWideChar(CP_UTF8, 0, channel, -1, wide_channel, len);
if (query != NULL) {
// query : To wide char
len = MultiByteToWideChar(CP_UTF8, 0, query, -1, NULL, 0);
wide_query = flb_malloc(sizeof(PWSTR) * len);
MultiByteToWideChar(CP_UTF8, 0, query, -1, wide_query, len);
ch->query = flb_strdup(query);
}

if (stored_bookmark) {
flags |= EvtSubscribeStartAfterBookmark;
Expand All @@ -70,11 +78,17 @@ struct winevtlog_channel *winevtlog_subscribe(const char *channel, int read_exis
flags |= EvtSubscribeToFutureEvents;
}

/* The wide_query parameter can handle NULL as `*` for retrieving all events.
* ref. https://learn.microsoft.com/en-us/windows/win32/api/winevt/nf-winevt-evtsubscribe
*/
ch->subscription = EvtSubscribe(NULL, signal_event, wide_channel, wide_query,
stored_bookmark, NULL, NULL, flags);
if (!ch->subscription) {
flb_error("[in_winevtlog] cannot subscribe '%s' (%i)", channel, GetLastError());
flb_free(ch->name);
if (ch->query != NULL) {
flb_free(ch->query);
}
flb_free(ch);
return NULL;
}
Expand All @@ -98,12 +112,18 @@ struct winevtlog_channel *winevtlog_subscribe(const char *channel, int read_exis
flb_error("[in_winevtlog] cannot subscribe '%s' (%i)", channel, GetLastError());
flb_free(wide_channel);
flb_free(ch->name);
if (ch->query != NULL) {
flb_free(ch->query);
}
flb_free(ch);
return NULL;
}
}

flb_free(wide_channel);
if (wide_query != NULL) {
flb_free(wide_query);
}

return ch;
}
Expand Down Expand Up @@ -142,6 +162,9 @@ static void close_handles(struct winevtlog_channel *ch)
void winevtlog_close(struct winevtlog_channel *ch)
{
flb_free(ch->name);
if (ch->query != NULL) {
flb_free(ch->query);
}
close_handles(ch);

flb_free(ch);
Expand Down Expand Up @@ -587,7 +610,7 @@ int winevtlog_read(struct winevtlog_channel *ch, struct winevtlog_config *ctx,
*
* "channels" are comma-separated names like "Setup,Security".
*/
struct mk_list *winevtlog_open_all(const char *channels, int read_existing_events, int ignore_missing_channels)
struct mk_list *winevtlog_open_all(const char *channels, struct winevtlog_config *ctx)
{
char *tmp;
char *channel;
Expand All @@ -611,12 +634,12 @@ struct mk_list *winevtlog_open_all(const char *channels, int read_existing_event

channel = strtok_s(tmp , ",", &state);
while (channel) {
ch = winevtlog_subscribe(channel, read_existing_events, NULL);
ch = winevtlog_subscribe(channel, ctx->read_existing_events, NULL, ctx->event_query);
if (ch) {
mk_list_add(&ch->_head, list);
}
else {
if (ignore_missing_channels) {
if (ctx->ignore_missing_channels) {
flb_debug("[in_winevtlog] channel '%s' does not exist", channel);
}
else {
Expand Down Expand Up @@ -746,7 +769,7 @@ int winevtlog_sqlite_load(struct winevtlog_channel *ch, struct flb_sqldb *db)
bookmark = EvtCreateBookmark(bookmark_xml);
if (bookmark) {
/* re-create subscription handles */
re_ch = winevtlog_subscribe(ch->name, FLB_FALSE, bookmark);
re_ch = winevtlog_subscribe(ch->name, FLB_FALSE, bookmark, ch->query);
if (re_ch != NULL) {
close_handles(ch);

Expand Down
4 changes: 3 additions & 1 deletion plugins/in_winevtlog/winevtlog.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct winevtlog_config {
int render_event_as_xml;
int use_ansi;
int ignore_missing_channels;
flb_sds_t event_query;

struct mk_list *active_channel;
struct flb_sqldb *db;
Expand All @@ -54,6 +55,7 @@ struct winevtlog_channel {
int count;

char *name;
char *query;
unsigned int time_updated;
unsigned int time_created;
struct mk_list _head;
Expand Down Expand Up @@ -83,7 +85,7 @@ int winevtlog_read(struct winevtlog_channel *ch,
*
* "channels" are comma-separated names like "Setup,Security".
*/
struct mk_list *winevtlog_open_all(const char *channels, int read_exising_events, int ignore_missing_channels);
struct mk_list *winevtlog_open_all(const char *channels, struct winevtlog_config *ctx);
void winevtlog_close_all(struct mk_list *list);

void winevtlog_pack_xml_event(WCHAR *system_xml, WCHAR *message,
Expand Down

0 comments on commit 5c19f46

Please sign in to comment.