Skip to content

in_winevtlog: Support remote access of winevtlog #10368

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 154 additions & 4 deletions plugins/in_winevtlog/in_winevtlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/

#include <fluent-bit/flb_compat.h>
#include <fluent-bit/flb_input_plugin.h>
#include <fluent-bit/flb_kernel.h>
#include <fluent-bit/flb_pack.h>
#include <fluent-bit/flb_utils.h>
Expand All @@ -36,6 +35,120 @@
static int in_winevtlog_collect(struct flb_input_instance *ins,
struct flb_config *config, void *in_context);

static wchar_t* convert_to_wide(struct winevtlog_config *ctx, char *str)
{
int size = 0;
wchar_t *buf = NULL;
DWORD err;

size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
if (size == 0) {
err = GetLastError();
flb_plg_error(ctx->ins, "Failed MultiByteToWideChar with error code (%d)", err);
return NULL;
}

buf = flb_calloc(1, sizeof(wchar_t) * size);
if (buf == NULL) {
flb_errno();
return NULL;
}
size = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, size);
if (size == 0) {
err = GetLastError();
flb_plg_error(ctx->ins, "Failed MultiByteToWideChar with error code (%d)", err);
flb_free(buf);
return NULL;
}

return buf;
}

static void in_winevtlog_session_destroy(struct winevtlog_session *session);

static struct winevtlog_session *in_winevtlog_session_create(struct winevtlog_config *ctx,
struct flb_config *config,
int *status)
{
int len;
struct winevtlog_session *session;
PWSTR wtmp;

if (ctx->remote_server == NULL) {
*status = WINEVTLOG_SESSION_SERVER_EMPTY;
return NULL;
}

session = flb_calloc(1, sizeof(struct winevtlog_session));
if (session == NULL) {
flb_errno();
*status = WINEVTLOG_SESSION_ALLOC_FAILED;
return NULL;
}

if (ctx->remote_server != NULL) {
session->server = convert_to_wide(ctx, ctx->remote_server);
if (session->server == NULL) {
in_winevtlog_session_destroy(session);
*status = WINEVTLOG_SESSION_FAILED_TO_CONVERT_WIDE;
return NULL;
}
}

if (ctx->remote_domain != NULL) {
session->domain = convert_to_wide(ctx, ctx->remote_domain);
if (session->domain == NULL) {
in_winevtlog_session_destroy(session);
*status = WINEVTLOG_SESSION_FAILED_TO_CONVERT_WIDE;
return NULL;
}
}

if (ctx->remote_username != NULL) {
session->username = convert_to_wide(ctx, ctx->remote_username);
if (session->username == NULL) {
in_winevtlog_session_destroy(session);
*status = WINEVTLOG_SESSION_FAILED_TO_CONVERT_WIDE;
return NULL;
}
}

if (ctx->remote_password != NULL) {
session->password = convert_to_wide(ctx, ctx->remote_password);
if (session->password == NULL) {
in_winevtlog_session_destroy(session);
*status = WINEVTLOG_SESSION_FAILED_TO_CONVERT_WIDE;
return NULL;
}
}

session->flags = EvtRpcLoginAuthDefault;
*status = WINEVTLOG_SESSION_CREATE_OK;

return session;
}

static void in_winevtlog_session_destroy(struct winevtlog_session *session)
{
if (session->server != NULL) {
flb_free(session->server);
}

if (session->domain != NULL) {
flb_free(session->domain);
}

if (session->username != NULL) {
flb_free(session->username);
}

if (session->password != NULL) {
flb_free(session->password);
}

flb_free(session);
}

static int in_winevtlog_init(struct flb_input_instance *in,
struct flb_config *config, void *data)
{
Expand All @@ -46,6 +159,8 @@ static int in_winevtlog_init(struct flb_input_instance *in,
struct mk_list *head;
struct winevtlog_channel *ch;
struct winevtlog_config *ctx;
struct winevtlog_session *session;
int status = WINEVTLOG_SESSION_CREATE_OK;

/* Initialize context */
ctx = flb_calloc(1, sizeof(struct winevtlog_config));
Expand All @@ -61,7 +176,7 @@ static int in_winevtlog_init(struct flb_input_instance *in,
flb_plg_error(in, "could not initialize event encoder");
flb_free(ctx);

return NULL;
return -1;
}

/* Load the config map */
Expand All @@ -72,6 +187,18 @@ static int in_winevtlog_init(struct flb_input_instance *in,
return -1;
}

/* Initialize session context */
session = in_winevtlog_session_create(ctx, config, &status);
if (status == WINEVTLOG_SESSION_ALLOC_FAILED ||
status == WINEVTLOG_SESSION_FAILED_TO_CONVERT_WIDE) {
flb_plg_error(in, "session is not created and invalid with status %d", status);
return -1;
}
else if (session == NULL) {
flb_plg_debug(in, "connect to local machine");
}
ctx->session = session;

/* Set up total reading size threshold */
if (ctx->total_size_threshold >= MINIMUM_THRESHOLD_SIZE &&
ctx->total_size_threshold <= MAXIMUM_THRESHOLD_SIZE) {
Expand Down Expand Up @@ -140,7 +267,7 @@ static int in_winevtlog_init(struct flb_input_instance *in,

mk_list_foreach(head, ctx->active_channel) {
ch = mk_list_entry(head, struct winevtlog_channel, _head);
winevtlog_sqlite_load(ch, ctx->db);
winevtlog_sqlite_load(ch, ctx, ctx->db);
flb_plg_debug(ctx->ins, "load channel<%s time=%u>",
ch->name, ch->time_created);
}
Expand Down Expand Up @@ -182,7 +309,7 @@ static int in_winevtlog_read_channel(struct flb_input_instance *ins,
ch->time_updated = time(NULL);
flb_plg_debug(ctx->ins, "save channel<%s time=%u>",
ch->name, ch->time_updated);
winevtlog_sqlite_save(ch, ctx->db);
winevtlog_sqlite_save(ch, ctx, ctx->db);
}

if (ctx->log_encoder->output_length > 0) {
Expand Down Expand Up @@ -235,6 +362,9 @@ static int in_winevtlog_exit(void *data, struct flb_config *config)
if (ctx->db) {
flb_sqldb_close(ctx->db);
}
if (ctx->session) {
in_winevtlog_session_destroy(ctx->session);
}
flb_free(ctx);

return 0;
Expand Down Expand Up @@ -296,6 +426,26 @@ static struct flb_config_map config_map[] = {
0, FLB_TRUE, offsetof(struct winevtlog_config, total_size_threshold),
"Specify reading limit for collecting Windows EventLog per a cycle"
},
{
FLB_CONFIG_MAP_STR, "remote.server", (char *)NULL,
0, FLB_TRUE, offsetof(struct winevtlog_config, remote_server),
"Specify server name of remote access for Windows EventLog"
},
{
FLB_CONFIG_MAP_STR, "remote.domain", (char *)NULL,
0, FLB_TRUE, offsetof(struct winevtlog_config, remote_domain),
"Specify domain name of remote access for Windows EventLog"
},
{
FLB_CONFIG_MAP_STR, "remote.username", (char *)NULL,
0, FLB_TRUE, offsetof(struct winevtlog_config, remote_username),
"Specify username of remote access for Windows EventLog"
},
{
FLB_CONFIG_MAP_STR, "remote.password", (char *)NULL,
0, FLB_TRUE, offsetof(struct winevtlog_config, remote_password),
"Specify password of remote access for Windows EventLog"
},
/* EOF */
{0}
};
Expand Down
4 changes: 3 additions & 1 deletion plugins/in_winevtlog/pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

static int pack_nullstr(struct winevtlog_config *ctx)
{
flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "");
return flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "");
}

static int pack_wstr(struct winevtlog_config *ctx, const wchar_t *wstr)
Expand Down Expand Up @@ -314,6 +314,8 @@ static int pack_sid(struct winevtlog_config *ctx, PSID sid, int extract_sid)

_snprintf_s(formatted, result_len, _TRUNCATE, "%s\\%s", domain, account);

size = strlen(formatted);

if (size > 0) {
flb_log_event_encoder_append_body_cstring(ctx->log_encoder, formatted);

Expand Down
Loading
Loading