diff options
Diffstat (limited to 'src/fluent-bit/plugins/in_winevtlog')
-rw-r--r-- | src/fluent-bit/plugins/in_winevtlog/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/fluent-bit/plugins/in_winevtlog/in_winevtlog.c | 279 | ||||
-rw-r--r-- | src/fluent-bit/plugins/in_winevtlog/pack.c | 625 | ||||
-rw-r--r-- | src/fluent-bit/plugins/in_winevtlog/winevtlog.c | 840 | ||||
-rw-r--r-- | src/fluent-bit/plugins/in_winevtlog/winevtlog.h | 134 |
5 files changed, 0 insertions, 1884 deletions
diff --git a/src/fluent-bit/plugins/in_winevtlog/CMakeLists.txt b/src/fluent-bit/plugins/in_winevtlog/CMakeLists.txt deleted file mode 100644 index 8f4c0e233..000000000 --- a/src/fluent-bit/plugins/in_winevtlog/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -set(src - in_winevtlog.c - pack.c - winevtlog.c) - -FLB_PLUGIN(in_winevtlog "${src}" "wevtapi") diff --git a/src/fluent-bit/plugins/in_winevtlog/in_winevtlog.c b/src/fluent-bit/plugins/in_winevtlog/in_winevtlog.c deleted file mode 100644 index 60c5bcecb..000000000 --- a/src/fluent-bit/plugins/in_winevtlog/in_winevtlog.c +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Fluent Bit - * ========== - * Copyright (C) 2019-2021 The Fluent Bit Authors - * Copyright (C) 2015-2018 Treasure Data Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#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> -#include <fluent-bit/flb_sqldb.h> -#include "winevtlog.h" - -#define DEFAULT_INTERVAL_SEC 1 -#define DEFAULT_INTERVAL_NSEC 0 -#define DEFAULT_THRESHOLD_SIZE 0x7ffff /* Default reading buffer size (512kb) */ - -static int in_winevtlog_collect(struct flb_input_instance *ins, - struct flb_config *config, void *in_context); - -static int in_winevtlog_init(struct flb_input_instance *in, - struct flb_config *config, void *data) -{ - int ret; - const char *tmp; - int read_existing_events = FLB_FALSE; - struct mk_list *head; - struct winevtlog_channel *ch; - struct winevtlog_config *ctx; - - /* Initialize context */ - ctx = flb_calloc(1, sizeof(struct winevtlog_config)); - if (ctx == NULL) { - flb_errno(); - return -1; - } - ctx->ins = in; - - ctx->log_encoder = flb_log_event_encoder_create(FLB_LOG_EVENT_FORMAT_DEFAULT); - - if (ctx->log_encoder == NULL) { - flb_plg_error(in, "could not initialize event encoder"); - flb_free(ctx); - - return NULL; - } - - /* Load the config map */ - ret = flb_input_config_map_set(in, (void *) ctx); - if (ret == -1) { - flb_log_event_encoder_destroy(ctx->log_encoder); - flb_free(ctx); - return -1; - } - - /* Set up total reading size threshold */ - ctx->total_size_threshold = DEFAULT_THRESHOLD_SIZE; - - /* Open channels */ - tmp = flb_input_get_property("channels", in); - if (!tmp) { - flb_plg_debug(ctx->ins, "no channel provided. listening to 'Application'"); - tmp = "Application"; - } - - 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); - flb_free(ctx); - return -1; - } - - /* Initialize SQLite DB (optional) */ - tmp = flb_input_get_property("db", in); - if (tmp) { - ctx->db = flb_sqldb_open(tmp, in->name, config); - if (!ctx->db) { - flb_plg_error(ctx->ins, "could not open/create database"); - winevtlog_close_all(ctx->active_channel); - flb_log_event_encoder_destroy(ctx->log_encoder); - flb_free(ctx); - return -1; - } - - ret = flb_sqldb_query(ctx->db, SQL_CREATE_CHANNELS, NULL, NULL); - if (ret != FLB_OK) { - flb_plg_error(ctx->ins, "could not create 'channels' table"); - flb_sqldb_close(ctx->db); - winevtlog_close_all(ctx->active_channel); - flb_log_event_encoder_destroy(ctx->log_encoder); - flb_free(ctx); - return -1; - } - - mk_list_foreach(head, ctx->active_channel) { - ch = mk_list_entry(head, struct winevtlog_channel, _head); - winevtlog_sqlite_load(ch, ctx->db); - flb_plg_debug(ctx->ins, "load channel<%s time=%u>", - ch->name, ch->time_created); - } - } - - /* Set the context */ - flb_input_set_context(in, ctx); - - /* Set the collector */ - ret = flb_input_set_collector_time(in, - in_winevtlog_collect, - ctx->interval_sec, - ctx->interval_nsec, - config); - if (ret == -1) { - flb_plg_error(ctx->ins, "could not set up a collector"); - } - ctx->coll_fd = ret; - - return 0; -} - -static int in_winevtlog_read_channel(struct flb_input_instance *ins, - struct winevtlog_config *ctx, - struct winevtlog_channel *ch) -{ - unsigned int read; - - if (winevtlog_read(ch, ctx, &read)) { - flb_plg_error(ctx->ins, "failed to read '%s'", ch->name); - return -1; - } - if (read == 0) { - return 0; - } - flb_plg_debug(ctx->ins, "read %u bytes from '%s'", read, ch->name); - - if (ctx->db) { - 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); - } - - if (ctx->log_encoder->output_length > 0) { - flb_input_log_append(ctx->ins, NULL, 0, - ctx->log_encoder->output_buffer, - ctx->log_encoder->output_length); - } - - flb_log_event_encoder_reset(ctx->log_encoder); - - return 0; -} - -static int in_winevtlog_collect(struct flb_input_instance *ins, - struct flb_config *config, void *in_context) -{ - struct winevtlog_config *ctx = in_context; - struct mk_list *head; - struct winevtlog_channel *ch; - - mk_list_foreach(head, ctx->active_channel) { - ch = mk_list_entry(head, struct winevtlog_channel, _head); - in_winevtlog_read_channel(ins, ctx, ch); - } - return 0; -} - -static void in_winevtlog_pause(void *data, struct flb_config *config) -{ - struct winevtlog_config *ctx = data; - flb_input_collector_pause(ctx->coll_fd, ctx->ins); -} - -static void in_winevtlog_resume(void *data, struct flb_config *config) -{ - struct winevtlog_config *ctx = data; - flb_input_collector_resume(ctx->coll_fd, ctx->ins); -} - -static int in_winevtlog_exit(void *data, struct flb_config *config) -{ - struct winevtlog_config *ctx = data; - - if (!ctx) { - return 0; - } - - winevtlog_close_all(ctx->active_channel); - - if (ctx->db) { - flb_sqldb_close(ctx->db); - } - flb_free(ctx); - - return 0; -} - -static struct flb_config_map config_map[] = { - { - FLB_CONFIG_MAP_STR, "channels", NULL, - 0, FLB_FALSE, 0, - "Specify a comma-separated list of channels to read from" - }, - { - FLB_CONFIG_MAP_STR, "db", NULL, - 0, FLB_FALSE, 0, - "Specify DB file to save read offsets" - }, - { - FLB_CONFIG_MAP_TIME, "interval_sec", "1s", - 0, FLB_TRUE, offsetof(struct winevtlog_config, interval_sec), - "Set the polling interval for each channel" - }, - { - FLB_CONFIG_MAP_INT, "interval_nsec", "0", - 0, FLB_TRUE, offsetof(struct winevtlog_config, interval_nsec), - "Set the polling interval for each channel (sub seconds)" - }, - { - FLB_CONFIG_MAP_BOOL, "string_inserts", "true", - 0, FLB_TRUE, offsetof(struct winevtlog_config, string_inserts), - "Whether to include StringInserts in output records" - }, - { - FLB_CONFIG_MAP_BOOL, "read_existing_events", "false", - 0, FLB_TRUE, offsetof(struct winevtlog_config, read_existing_events), - "Whether to consume at oldest records in channels" - }, - { - FLB_CONFIG_MAP_BOOL, "render_event_as_xml", "false", - 0, FLB_TRUE, offsetof(struct winevtlog_config, render_event_as_xml), - "Whether to consume at oldest records in channels" - }, - { - FLB_CONFIG_MAP_BOOL, "use_ansi", "false", - 0, FLB_TRUE, offsetof(struct winevtlog_config, use_ansi), - "Use ANSI encoding on eventlog messages" - }, - { - FLB_CONFIG_MAP_BOOL, "ignore_missing_channels", "false", - 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} -}; - -struct flb_input_plugin in_winevtlog_plugin = { - .name = "winevtlog", - .description = "Windows EventLog using winevt.h API", - .cb_init = in_winevtlog_init, - .cb_pre_run = NULL, - .cb_collect = in_winevtlog_collect, - .cb_flush_buf = NULL, - .cb_pause = in_winevtlog_pause, - .cb_resume = in_winevtlog_resume, - .cb_exit = in_winevtlog_exit, - .config_map = config_map -}; diff --git a/src/fluent-bit/plugins/in_winevtlog/pack.c b/src/fluent-bit/plugins/in_winevtlog/pack.c deleted file mode 100644 index 28075436b..000000000 --- a/src/fluent-bit/plugins/in_winevtlog/pack.c +++ /dev/null @@ -1,625 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Fluent Bit - * ========== - * Copyright (C) 2019-2021 The Fluent Bit Authors - * Copyright (C) 2015-2018 Treasure Data Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fluent-bit/flb_compat.h> -#include <fluent-bit/flb_mem.h> -#include <fluent-bit/flb_utils.h> -#include <fluent-bit/flb_pack.h> -#include <fluent-bit/flb_input_plugin.h> -#include <msgpack.h> -#include <sddl.h> -#include <locale.h> -#include "winevtlog.h" - -#define FORMAT_ISO8601 "%Y-%m-%d %H:%M:%S %z" - -#define BINDATA(evt) ((unsigned char *) (evt) + (evt)->DataOffset) - -static int pack_nullstr(struct winevtlog_config *ctx) -{ - flb_log_event_encoder_append_body_cstring(ctx->log_encoder, ""); -} - -static int pack_wstr(struct winevtlog_config *ctx, const wchar_t *wstr) -{ - int size; - char *buf; - UINT code_page = CP_UTF8; - LPCSTR defaultChar = L" "; - - if (ctx->use_ansi) { - code_page = CP_ACP; - } - - /* Compute the buffer size first */ - size = WideCharToMultiByte(code_page, 0, wstr, -1, NULL, 0, NULL, NULL); - if (size == 0) { - return -1; - } - - buf = flb_malloc(size); - if (buf == NULL) { - flb_errno(); - return -1; - } - - /* Convert UTF-16 into UTF-8 */ - size = WideCharToMultiByte(code_page, 0, wstr, -1, buf, size, defaultChar, NULL); - if (size == 0) { - flb_free(buf); - return -1; - } - - /* Pack buf except the trailing '\0' */ - flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, size - 1); - - flb_free(buf); - return 0; -} - -static int pack_binary(struct winevtlog_config *ctx, PBYTE bin, size_t length) -{ - const char *HEX_TABLE = "0123456789ABCDEF"; - char *buffer; - int size = length * 2; - size_t i, j; - unsigned int idx = 0; - - if (length == 0) { - pack_nullstr(ctx->log_encoder); - return 0; - } - - buffer = flb_malloc(size); - if (buffer == NULL) { - flb_errno(); - return -1; - } - - for (i = 0; i < length; i++) { - for (j = 0; j < 2; j++) { - idx = (unsigned int)(bin[i] >> (j * 4) & 0x0F); - buffer[2*i+(1-j)] = HEX_TABLE[idx]; - } - } - - flb_log_event_encoder_append_body_string(ctx->log_encoder, buffer, size); - - flb_free(buffer); - - return 0; -} - -static int pack_guid(struct winevtlog_config *ctx, const GUID *guid) -{ - LPOLESTR p = NULL; - - if (FAILED(StringFromCLSID(guid, &p))) { - return -1; - } - if (pack_wstr(ctx, p)) { - CoTaskMemFree(p); - return -1; - } - - CoTaskMemFree(p); - - return 0; -} - -static int pack_hex32(struct winevtlog_config *ctx, int32_t hex) -{ - CHAR buffer[32]; - size_t size = _countof(buffer); - - _snprintf_s(buffer, - size, - _TRUNCATE, - "0x%lx", - hex); - size = strlen(buffer); - if (size > 0) { - flb_log_event_encoder_append_body_cstring(ctx->log_encoder, buffer); - - return 0; - } - - return -1; -} - -static int pack_hex64(struct winevtlog_config *ctx, int64_t hex) -{ - CHAR buffer[32]; - size_t size = _countof(buffer); - - _snprintf_s(buffer, - size, - _TRUNCATE, - "0x%llx", - hex); - - size = strlen(buffer); - if (size > 0) { - flb_log_event_encoder_append_body_cstring(ctx->log_encoder, buffer); - - return 0; - } - - return -1; -} - - -static int pack_keywords(struct winevtlog_config *ctx, uint64_t keywords) -{ - CHAR buffer[32]; - size_t size = _countof(buffer); - - _snprintf_s(buffer, - size, - _TRUNCATE, - "0x%llx", - keywords); - - size = strlen(buffer); - - flb_log_event_encoder_append_body_cstring(ctx->log_encoder, buffer); - - return 0; -} - -static int pack_systemtime(struct winevtlog_config *ctx, SYSTEMTIME *st) -{ - CHAR buf[64]; - size_t len = 0; - _locale_t locale; - TIME_ZONE_INFORMATION tzi; - SYSTEMTIME st_local; - - GetTimeZoneInformation(&tzi); - - locale = _get_current_locale(); - if (locale == NULL) { - return -1; - } - if (st != NULL) { - SystemTimeToTzSpecificLocalTime(&tzi, st, &st_local); - - struct tm tm = {st_local.wSecond, - st_local.wMinute, - st_local.wHour, - st_local.wDay, - st_local.wMonth-1, - st_local.wYear-1900, - st_local.wDayOfWeek, 0, 0}; - len = _strftime_l(buf, 64, FORMAT_ISO8601, &tm, locale); - if (len == 0) { - flb_errno(); - _free_locale(locale); - return -1; - } - _free_locale(locale); - - flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len); - } - else { - return -1; - } - - return 0; -} - -static int pack_filetime(struct winevtlog_config *ctx, ULONGLONG filetime) -{ - LARGE_INTEGER timestamp; - CHAR buf[64]; - size_t len = 0; - FILETIME ft, ft_local; - SYSTEMTIME st; - _locale_t locale; - - locale = _get_current_locale(); - if (locale == NULL) { - return -1; - } - timestamp.QuadPart = filetime; - ft.dwHighDateTime = timestamp.HighPart; - ft.dwLowDateTime = timestamp.LowPart; - FileTimeToLocalFileTime(&ft, &ft_local); - if (FileTimeToSystemTime(&ft_local, &st)) { - struct tm tm = {st.wSecond, st.wMinute, st.wHour, st.wDay, st.wMonth-1, st.wYear-1900, st.wDayOfWeek, 0, 0}; - len = _strftime_l(buf, 64, FORMAT_ISO8601, &tm, locale); - if (len == 0) { - flb_errno(); - _free_locale(locale); - return -1; - } - _free_locale(locale); - - flb_log_event_encoder_append_body_string(ctx->log_encoder, buf, len); - } - else { - return -1; - } - - return 0; -} - -static int pack_sid(struct winevtlog_config *ctx, PSID sid) -{ - size_t size; - LPWSTR wide_sid = NULL; - int ret = -1; - - if (ConvertSidToStringSidW(sid, &wide_sid)) { - ret = pack_wstr(ctx, wide_sid); - - LocalFree(wide_sid); - return ret; - } - - return ret; -} - -static void pack_string_inserts(struct winevtlog_config *ctx, PEVT_VARIANT values, DWORD count) -{ - int i; - int ret; - - ret = flb_log_event_encoder_body_begin_array(ctx->log_encoder); - - for (i = 0; i < count; i++) { - if (values[i].Type & EVT_VARIANT_TYPE_ARRAY) { - continue; - } - - switch (values[i].Type & EVT_VARIANT_TYPE_MASK) { - case EvtVarTypeNull: - pack_nullstr(ctx); - break; - case EvtVarTypeString: - if (pack_wstr(ctx, values[i].StringVal)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeAnsiString: - if (pack_wstr(ctx, values[i].AnsiStringVal)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeSByte: - flb_log_event_encoder_append_body_int8(ctx->log_encoder, values[i].SByteVal); - break; - case EvtVarTypeByte: - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, values[i].ByteVal); - break; - case EvtVarTypeInt16: - flb_log_event_encoder_append_body_int16(ctx->log_encoder, values[i].Int16Val); - break; - case EvtVarTypeUInt16: - flb_log_event_encoder_append_body_uint16(ctx->log_encoder, values[i].UInt16Val); - break; - case EvtVarTypeInt32: - flb_log_event_encoder_append_body_int32(ctx->log_encoder, values[i].Int32Val); - break; - case EvtVarTypeUInt32: - flb_log_event_encoder_append_body_uint32(ctx->log_encoder, values[i].UInt32Val); - break; - case EvtVarTypeInt64: - flb_log_event_encoder_append_body_int64(ctx->log_encoder, values[i].Int64Val); - break; - case EvtVarTypeUInt64: - flb_log_event_encoder_append_body_uint64(ctx->log_encoder, values[i].UInt64Val); - break; - case EvtVarTypeSingle: - flb_log_event_encoder_append_body_double(ctx->log_encoder, values[i].SingleVal); - break; - case EvtVarTypeDouble: - flb_log_event_encoder_append_body_double(ctx->log_encoder, values[i].DoubleVal); - break; - case EvtVarTypeBoolean: - flb_log_event_encoder_append_body_boolean(ctx->log_encoder, (int) values[i].BooleanVal); - break; - case EvtVarTypeGuid: - if (pack_guid(ctx, values[i].GuidVal)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeSizeT: - flb_log_event_encoder_append_body_uint64(ctx->log_encoder, values[i].SizeTVal); - break; - case EvtVarTypeFileTime: - if (pack_filetime(ctx, values[i].FileTimeVal)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeSysTime: - if (pack_systemtime(ctx, values[i].SysTimeVal)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeSid: - if (pack_sid(ctx, values[i].SidVal)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeHexInt32: - if (pack_hex32(ctx, values[i].Int32Val)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeHexInt64: - if (pack_hex64(ctx, values[i].Int64Val)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeEvtXml: - if (pack_wstr(ctx, values[i].XmlVal, ctx)) { - pack_nullstr(ctx); - } - break; - case EvtVarTypeBinary: - if (pack_binary(ctx, values[i].BinaryVal, values[i].Count)) { - pack_nullstr(ctx); - } - break; - default: - flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "?"); - } - } - - if (ret == FLB_EVENT_ENCODER_SUCCESS) { - ret = flb_log_event_encoder_body_commit_array(ctx->log_encoder); - } - -} - -void winevtlog_pack_xml_event(WCHAR *system_xml, WCHAR *message, - PEVT_VARIANT string_inserts, UINT count_inserts, struct winevtlog_channel *ch, - struct winevtlog_config *ctx) -{ - int ret; - - ret = flb_log_event_encoder_begin_record(ctx->log_encoder); - - if (ret == FLB_EVENT_ENCODER_SUCCESS) { - ret = flb_log_event_encoder_set_current_timestamp(ctx->log_encoder); - } - - - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "System"); - - if (pack_wstr(ctx, system_xml)) { - pack_nullstr(ctx); - } - - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Message"); - - if (pack_wstr(ctx, message)) { - pack_nullstr(ctx); - } - - if (ctx->string_inserts) { - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "StringInserts"); - - pack_string_inserts(ctx, string_inserts, count_inserts); - } - - if (ret == FLB_EVENT_ENCODER_SUCCESS) { - ret = flb_log_event_encoder_commit_record(ctx->log_encoder); - } -} - -void winevtlog_pack_event(PEVT_VARIANT system, WCHAR *message, - PEVT_VARIANT string_inserts, UINT count_inserts, struct winevtlog_channel *ch, - struct winevtlog_config *ctx) -{ - int ret; - size_t len; - int count = 19; - - if (ctx->string_inserts) { - count++; - } - - ret = flb_log_event_encoder_begin_record(ctx->log_encoder); - - if (ret == FLB_EVENT_ENCODER_SUCCESS) { - ret = flb_log_event_encoder_set_current_timestamp(ctx->log_encoder); - } - - /* ProviderName */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "ProviderName"); - - if (pack_wstr(ctx, system[EvtSystemProviderName].StringVal)) { - pack_nullstr(ctx); - } - - /* ProviderGuid */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "ProviderGuid"); - - if (EvtVarTypeNull != system[EvtSystemProviderGuid].Type) { - if (pack_guid(ctx, system[EvtSystemProviderGuid].GuidVal)) { - pack_nullstr(ctx); - } - } - else { - pack_nullstr(ctx); - } - - /* Qualifiers */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Qualifiers"); - - if (EvtVarTypeNull != system[EvtSystemQualifiers].Type) { - flb_log_event_encoder_append_body_uint16(ctx->log_encoder, system[EvtSystemQualifiers].UInt16Val); - } - else { - pack_nullstr(ctx); - } - - /* EventID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "EventID"); - - if (EvtVarTypeNull != system[EvtSystemEventID].Type) { - flb_log_event_encoder_append_body_uint16(ctx->log_encoder, system[EvtSystemEventID].UInt16Val); - } - else { - pack_nullstr(ctx); - } - - /* Version */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Version"); - - if (EvtVarTypeNull != system[EvtSystemVersion].Type) { - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, system[EvtSystemVersion].ByteVal); - } - else { - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, 0); - } - - /* Level */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Level"); - - if (EvtVarTypeNull != system[EvtSystemLevel].Type) { - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, system[EvtSystemLevel].ByteVal); - } - else { - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, 0); - } - - /* Task */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Task"); - - if (EvtVarTypeNull != system[EvtSystemTask].Type) { - flb_log_event_encoder_append_body_uint16(ctx->log_encoder, system[EvtSystemTask].UInt16Val); - } - else { - flb_log_event_encoder_append_body_uint16(ctx->log_encoder, 0); - } - - /* Opcode */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Opcode"); - - if (EvtVarTypeNull != system[EvtSystemOpcode].Type) { - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, system[EvtSystemOpcode].ByteVal); - } - else { - flb_log_event_encoder_append_body_uint8(ctx->log_encoder, 0); - } - - /* Keywords */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Keywords"); - - if (EvtVarTypeNull != system[EvtSystemKeywords].Type) { - pack_keywords(ctx, system[EvtSystemKeywords].UInt64Val); - } - else { - flb_log_event_encoder_append_body_uint64(ctx->log_encoder, 0); - } - - /* TimeCreated */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "TimeCreated"); - - if (pack_filetime(ctx, system[EvtSystemTimeCreated].FileTimeVal)) { - pack_nullstr(ctx); - } - - /* EventRecordID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "EventRecordID"); - - if (EvtVarTypeNull != system[EvtSystemEventRecordId].Type) { - flb_log_event_encoder_append_body_uint64(ctx->log_encoder, system[EvtSystemEventRecordId].UInt64Val); - } - else { - flb_log_event_encoder_append_body_uint64(ctx->log_encoder, 0); - } - - /* ActivityID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "ActivityID"); - - if (pack_guid(ctx, system[EvtSystemActivityID].GuidVal)) { - pack_nullstr(ctx); - } - - /* Related ActivityID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "RelatedActivityID"); - - if (pack_guid(ctx, system[EvtSystemRelatedActivityID].GuidVal)) { - pack_nullstr(ctx); - } - - /* ProcessID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "ProcessID"); - - if (EvtVarTypeNull != system[EvtSystemProcessID].Type) { - flb_log_event_encoder_append_body_uint32(ctx->log_encoder, system[EvtSystemProcessID].UInt32Val); - } - else { - flb_log_event_encoder_append_body_uint32(ctx->log_encoder, 0); - } - - /* ThreadID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "ThreadID"); - - if (EvtVarTypeNull != system[EvtSystemThreadID].Type) { - flb_log_event_encoder_append_body_uint32(ctx->log_encoder, system[EvtSystemThreadID].UInt32Val); - } - else { - flb_log_event_encoder_append_body_uint32(ctx->log_encoder, 0); - } - - /* Channel */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Channel"); - - if (pack_wstr(ctx, system[EvtSystemChannel].StringVal)) { - pack_nullstr(ctx); - } - - /* Computer */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Computer"); - - if (pack_wstr(ctx, system[EvtSystemComputer].StringVal)) { - pack_nullstr(ctx); - } - - /* UserID */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "UserID"); - - if (pack_sid(ctx, system[EvtSystemUserID].SidVal)) { - pack_nullstr(ctx); - } - - /* Message */ - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "Message"); - - if (pack_wstr(ctx, message)) { - pack_nullstr(ctx); - } - - /* String Inserts */ - if (ctx->string_inserts) { - ret = flb_log_event_encoder_append_body_cstring(ctx->log_encoder, "StringInserts"); - - pack_string_inserts(ctx, string_inserts, count_inserts); - } - - if (ret == FLB_EVENT_ENCODER_SUCCESS) { - ret = flb_log_event_encoder_commit_record(ctx->log_encoder); - } -} diff --git a/src/fluent-bit/plugins/in_winevtlog/winevtlog.c b/src/fluent-bit/plugins/in_winevtlog/winevtlog.c deleted file mode 100644 index 09d3f9624..000000000 --- a/src/fluent-bit/plugins/in_winevtlog/winevtlog.c +++ /dev/null @@ -1,840 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Fluent Bit - * ========== - * Copyright (C) 2019-2021 The Fluent Bit Authors - * Copyright (C) 2015-2018 Treasure Data Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fluent-bit/flb_compat.h> -#include <fluent-bit/flb_info.h> -#include <fluent-bit/flb_utils.h> -#include <fluent-bit/flb_sqldb.h> -#include <fluent-bit/flb_input.h> -#include "winevtlog.h" - -#define EVENT_PROVIDER_NAME_LENGTH 256 - -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, const char *query) -{ - struct winevtlog_channel *ch; - EVT_HANDLE bookmark = NULL; - HANDLE signal_event = NULL; - DWORD len; - DWORD flags = 0L; - PWSTR wide_channel = NULL; - PWSTR wide_query = NULL; - void *buf; - - ch = flb_calloc(1, sizeof(struct winevtlog_channel)); - if (ch == NULL) { - flb_errno(); - return NULL; - } - - ch->name = flb_strdup(channel); - if (!ch->name) { - flb_errno(); - 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; - } else if (read_existing_events) { - flags |= EvtSubscribeStartAtOldestRecord; - } else { - 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; - } - ch->signal_event = signal_event; - - if (stored_bookmark) { - ch->bookmark = stored_bookmark; - } - else { - bookmark = EvtCreateBookmark(NULL); - if (bookmark) { - ch->bookmark = bookmark; - } - else { - if (ch->subscription) { - EvtClose(ch->subscription); - } - if (signal_event) { - CloseHandle(signal_event); - } - 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; -} - -BOOL cancel_subscription(struct winevtlog_channel *ch) -{ - return EvtCancel(ch->subscription); -} - -static void close_handles(struct winevtlog_channel *ch) -{ - int i; - - if (ch->subscription) { - EvtClose(ch->subscription); - ch->subscription = NULL; - } - if (ch->signal_event) { - CloseHandle(ch->signal_event); - ch->signal_event = NULL; - } - if (ch->bookmark) { - EvtClose(ch->bookmark); - ch->bookmark = NULL; - } - for (i = 0; i < ch->count; i++) { - if (ch->events[i]) { - EvtClose(ch->events[i]); - ch->events[i] = NULL; - } - } - ch->count = 0; -} - - -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); -} - -// Render the event as an XML string and print it. -PWSTR render_event(EVT_HANDLE hEvent, DWORD flags, unsigned int *event_size) -{ - DWORD status = ERROR_SUCCESS; - DWORD buffer_size = 0; - DWORD buffer_used = 0; - DWORD count = 0; - LPWSTR event_xml = NULL; - - if (flags != EvtRenderEventXml && flags != EvtRenderBookmark) { - flb_error("Invalid flags is specified: %d", flags); - return NULL; - } - - if (!EvtRender(NULL, hEvent, flags, buffer_size, event_xml, &buffer_used, &count)) { - status = GetLastError(); - if (status == ERROR_INSUFFICIENT_BUFFER) { - buffer_size = buffer_used; - /* return buffer size */ - *event_size = buffer_size; - event_xml = (LPWSTR)flb_malloc(buffer_size); - if (event_xml) { - EvtRender(NULL, hEvent, flags, buffer_size, event_xml, &buffer_used, &count); - } - else { - flb_error("malloc failed"); - goto cleanup; - } - } - - status = GetLastError(); - if (status != ERROR_SUCCESS) { - flb_error("EvtRender failed with %d", GetLastError()); - goto cleanup; - } - } - - return event_xml; - -cleanup: - - if (event_xml) { - flb_free(event_xml); - } - - return NULL; -} - -DWORD render_system_event(EVT_HANDLE event, PEVT_VARIANT *system, unsigned int *system_size) -{ - DWORD status = ERROR_SUCCESS; - EVT_HANDLE context = NULL; - DWORD buffer_size = 0; - DWORD buffer_used = 0; - DWORD count = 0; - PEVT_VARIANT rendered_system = NULL; - - context = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem); - if (NULL == context) { - status = GetLastError(); - flb_error("failed to create RenderContext with %d", status); - - goto cleanup; - } - if (!EvtRender(context, - event, - EvtRenderEventValues, - buffer_size, - rendered_system, - &buffer_used, - &count)) { - status = GetLastError(); - - if (status == ERROR_INSUFFICIENT_BUFFER) { - buffer_size = buffer_used; - rendered_system = (PEVT_VARIANT)flb_malloc(buffer_size); - if (rendered_system) { - EvtRender(context, - event, - EvtRenderEventValues, - buffer_size, - rendered_system, - &buffer_used, - &count); - status = GetLastError(); - *system_size = buffer_used; - } else { - if (rendered_system) - flb_free(rendered_system); - - flb_error("failed to malloc memory with %d", status); - - goto cleanup; - } - } - - if (ERROR_SUCCESS != status) { - EvtClose(context); - flb_free(rendered_system); - - return status; - } - } - - *system = rendered_system; - -cleanup: - - if (context) { - EvtClose(context); - } - - return status; -} - - -PWSTR get_message(EVT_HANDLE metadata, EVT_HANDLE handle, unsigned int *message_size) -{ - WCHAR* buffer = NULL; - DWORD status = ERROR_SUCCESS; - DWORD buffer_size = 0; - DWORD buffer_used = 0; - LPVOID format_message_buffer; - WCHAR* message = NULL; - char *error_message = NULL; - - // Get the size of the buffer - if (!EvtFormatMessage(metadata, handle, 0, 0, NULL, - EvtFormatMessageEvent, buffer_size, buffer, &buffer_used)) { - status = GetLastError(); - if (ERROR_INSUFFICIENT_BUFFER == status) { - buffer_size = buffer_used; - buffer = flb_malloc(sizeof(WCHAR) * buffer_size); - if (!buffer) { - flb_error("failed to malloc message buffer"); - - goto cleanup; - } - if (!EvtFormatMessage(metadata, - handle, - 0xffffffff, - 0, - NULL, - EvtFormatMessageEvent, - buffer_size, - buffer, - &buffer_used)) { - status = GetLastError(); - *message_size = buffer_used; - - if (status != ERROR_EVT_UNRESOLVED_VALUE_INSERT) { - switch (status) { - case ERROR_EVT_MESSAGE_NOT_FOUND: - case ERROR_EVT_MESSAGE_ID_NOT_FOUND: - case ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND: - case ERROR_RESOURCE_DATA_NOT_FOUND: - case ERROR_RESOURCE_TYPE_NOT_FOUND: - case ERROR_RESOURCE_NAME_NOT_FOUND: - case ERROR_RESOURCE_LANG_NOT_FOUND: - case ERROR_MUI_FILE_NOT_FOUND: - case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: - { - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - status, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (WCHAR*)(&format_message_buffer), - 0, - NULL) == 0) - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - status, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (WCHAR*)(&format_message_buffer), - 0, - NULL); - error_message = convert_wstr((WCHAR*)format_message_buffer, CP_ACP); - flb_error("Failed to get message with %d, err = %s", status, error_message); - flb_free(error_message); - - message = _wcsdup((WCHAR*)format_message_buffer); - LocalFree(format_message_buffer); - - goto cleanup; - } - } - - if (status != ERROR_INSUFFICIENT_BUFFER) { - flb_error("failed with %d", status); - goto cleanup; - } - } - } - } - } - - message = _wcsdup(buffer); - -cleanup: - if (buffer) { - flb_free(buffer); - } - - return message; -} - -PWSTR get_description(EVT_HANDLE handle, LANGID langID, unsigned int *message_size) -{ - WCHAR *buffer[EVENT_PROVIDER_NAME_LENGTH]; - PEVT_VARIANT values = NULL; - DWORD buffer_used = 0; - DWORD status = ERROR_SUCCESS; - DWORD count = 0; - WCHAR *message = NULL; - EVT_HANDLE metadata = NULL; - - PCWSTR properties[] = { L"Event/System/Provider/@Name" }; - EVT_HANDLE context = - EvtCreateRenderContext(1, properties, EvtRenderContextValues); - if (context == NULL) { - flb_error("Failed to create renderContext"); - goto cleanup; - } - - if (EvtRender(context, - handle, - EvtRenderEventValues, - EVENT_PROVIDER_NAME_LENGTH, - buffer, - &buffer_used, - &count) != FALSE){ - status = ERROR_SUCCESS; - } - else { - status = GetLastError(); - } - - if (status != ERROR_SUCCESS) { - flb_error("failed to query RenderContextValues"); - goto cleanup; - } - values = (PEVT_VARIANT)buffer; - - metadata = EvtOpenPublisherMetadata( - NULL, // TODO: Remote handle - values[0].StringVal, - NULL, - MAKELCID(langID, SORT_DEFAULT), - 0); - if (metadata == NULL) { - goto cleanup; - } - - message = get_message(metadata, handle, message_size); - -cleanup: - if (context) { - EvtClose(context); - } - - if (metadata) { - EvtClose(metadata); - } - - return message; -} - -int get_string_inserts(EVT_HANDLE handle, PEVT_VARIANT *string_inserts_values, - UINT *prop_count, unsigned int *string_inserts_size) -{ - PEVT_VARIANT values; - DWORD buffer_size = 0; - DWORD buffer_size_used = 0; - DWORD count = 0; - BOOL succeeded = FLB_TRUE; - - EVT_HANDLE context = EvtCreateRenderContext(0, NULL, EvtRenderContextUser); - if (context == NULL) { - flb_error("Failed to create renderContext"); - succeeded = FLB_FALSE; - goto cleanup; - } - - // Get the size of the buffer - EvtRender(context, handle, EvtRenderEventValues, 0, NULL, &buffer_size, &count); - values = (PEVT_VARIANT)flb_malloc(buffer_size); - - succeeded = EvtRender(context, - handle, - EvtRenderContextValues, - buffer_size, - values, - &buffer_size_used, - &count); - - if (!succeeded) { - flb_error("Failed to get string inserts with %d\n", GetLastError()); - goto cleanup; - } - - *prop_count = count; - *string_inserts_values = values; - *string_inserts_size = buffer_size; - -cleanup: - - if (context != NULL) { - EvtClose(context); - } - - return succeeded; -} - -static int winevtlog_next(struct winevtlog_channel *ch, int hit_threshold) -{ - EVT_HANDLE events[SUBSCRIBE_ARRAY_SIZE]; - DWORD count = 0; - DWORD status = ERROR_SUCCESS; - BOOL has_next = FALSE; - int i; - - /* If subscription handle is NULL, it should return false. */ - if (!ch->subscription) { - flb_error("Invalid subscription is passed"); - return FLB_FALSE; - } - - if (hit_threshold) { - return FLB_FALSE; - } - - has_next = EvtNext(ch->subscription, SUBSCRIBE_ARRAY_SIZE, - events, INFINITE, 0, &count); - - if (!has_next) { - status = GetLastError(); - if (ERROR_CANCELLED == status) { - return FLB_FALSE; - } - if (ERROR_NO_MORE_ITEMS != status) { - return FLB_FALSE; - } - } - - if (status == ERROR_SUCCESS) { - ch->count = count; - for (i = 0; i < count; i++) { - ch->events[i] = events[i]; - EvtUpdateBookmark(ch->bookmark, ch->events[i]); - } - - return FLB_TRUE; - } - - return FLB_FALSE; -} - -/* - * Read from an open Windows Event Log channel. - */ -int winevtlog_read(struct winevtlog_channel *ch, struct winevtlog_config *ctx, - unsigned int *read) -{ - DWORD status = ERROR_SUCCESS; - PWSTR system_xml = NULL; - unsigned int system_size = 0; - unsigned int message_size = 0; - unsigned int string_inserts_size = 0; - int hit_threshold = FLB_FALSE; - unsigned int read_size = 0; - PWSTR message = NULL; - PEVT_VARIANT rendered_system = NULL; - PEVT_VARIANT string_inserts = NULL; - UINT count_inserts = 0; - DWORD i = 0; - - while (winevtlog_next(ch, hit_threshold)) { - for (i = 0; i < ch->count; i++) { - if (ctx->render_event_as_xml) { - system_xml = render_event(ch->events[i], EvtRenderEventXml, &system_size); - message = get_description(ch->events[i], LANG_NEUTRAL, &message_size); - get_string_inserts(ch->events[i], &string_inserts, &count_inserts, &string_inserts_size); - if (system_xml) { - /* Caluculate total allocated size: system + message + string_inserts */ - read_size += (system_size + message_size + string_inserts_size); - winevtlog_pack_xml_event(system_xml, message, string_inserts, - count_inserts, ch, ctx); - - flb_free(string_inserts); - flb_free(system_xml); - if (message) - flb_free(message); - } - } - else { - render_system_event(ch->events[i], &rendered_system, &system_size); - message = get_description(ch->events[i], LANG_NEUTRAL, &message_size); - get_string_inserts(ch->events[i], &string_inserts, &count_inserts, &string_inserts_size); - if (rendered_system) { - /* Caluculate total allocated size: system + message + string_inserts */ - read_size += (system_size + message_size + string_inserts_size); - winevtlog_pack_event(rendered_system, message, string_inserts, - count_inserts, ch, ctx); - - flb_free(string_inserts); - flb_free(rendered_system); - if (message) - flb_free(message); - } - } - } - - /* Closes any events in case an error occurred above. */ - for (i = 0; i < ch->count; i++) { - if (NULL != ch->events[i]) { - EvtClose(ch->events[i]); - ch->events[i] = NULL; - } - } - - if (read_size > ctx->total_size_threshold) { - hit_threshold = FLB_TRUE; - /* hit reading threshold on read, then break. */ - break; - } - } - - *read = read_size; - - return 0; -} - -/* - * Open multiple channels at once. The return value is a linked - * list of winevtlog_channel objects. - * - * "channels" are comma-separated names like "Setup,Security". - */ -struct mk_list *winevtlog_open_all(const char *channels, struct winevtlog_config *ctx) -{ - char *tmp; - char *channel; - char *state; - struct winevtlog_channel *ch; - struct mk_list *list; - - tmp = flb_strdup(channels); - if (!tmp) { - flb_errno(); - return NULL; - } - - list = flb_malloc(sizeof(struct mk_list)); - if (!list) { - flb_errno(); - flb_free(tmp); - return NULL; - } - mk_list_init(list); - - channel = strtok_s(tmp , ",", &state); - while (channel) { - ch = winevtlog_subscribe(channel, ctx->read_existing_events, NULL, ctx->event_query); - if (ch) { - mk_list_add(&ch->_head, list); - } - else { - if (ctx->ignore_missing_channels) { - flb_debug("[in_winevtlog] channel '%s' does not exist", channel); - } - else { - flb_free(tmp); - winevtlog_close_all(list); - return NULL; - } - } - channel = strtok_s(NULL, ",", &state); - } - - if (mk_list_size(list) == 0) { - flb_free(tmp); - winevtlog_close_all(list); - return NULL; - } - - flb_free(tmp); - return list; -} - -void winevtlog_close_all(struct mk_list *list) -{ - struct winevtlog_channel *ch; - struct mk_list *head; - struct mk_list *tmp; - - mk_list_foreach_safe(head, tmp, list) { - ch = mk_list_entry(head, struct winevtlog_channel, _head); - mk_list_del(&ch->_head); - winevtlog_close(ch); - } - flb_free(list); -} - -/* - * Callback function for flb_sqldb_query(). - */ -static int winevtlog_sqlite_callback(void *data, int argc, char **argv, char **cols) -{ - struct winevtlog_sqlite_record *p = data; - - p->name = argv[0]; - p->bookmark_xml = strdup(argv[1]); - p->time_updated = (unsigned int) strtoul(argv[2], NULL, 10); - p->created = (unsigned int) strtoul(argv[3], NULL, 10); - return 0; -} - -static wchar_t* convert_str(char *str) -{ - int size = 0; - wchar_t *buf = NULL; - - size = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); - if (size == 0) { - return NULL; - } - - buf = flb_malloc(sizeof(PWSTR) * size); - if (buf == NULL) { - flb_errno(); - return NULL; - } - size = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, size); - if (size == 0) { - flb_free(buf); - return NULL; - } - - return buf; -} - -static char* convert_wstr(wchar_t *wstr, UINT codePage) -{ - int size = 0; - char *buf = NULL; - - size = WideCharToMultiByte(codePage, 0, wstr, -1, NULL, 0, NULL, NULL); - if (size == 0) { - return NULL; - } - - buf = flb_malloc(size); - if (buf == NULL) { - flb_errno(); - return NULL; - } - size = WideCharToMultiByte(codePage, 0, wstr, -1, buf, size, NULL, NULL); - if (size == 0) { - flb_free(buf); - return NULL; - } - - return buf; -} - -/* - * Load the bookmark from SQLite DB. - */ -int winevtlog_sqlite_load(struct winevtlog_channel *ch, struct flb_sqldb *db) -{ - int ret; - char query[1024]; - struct winevtlog_sqlite_record record = {0}; - EVT_HANDLE bookmark = NULL; - PWSTR bookmark_xml = NULL; - struct winevtlog_channel *re_ch = NULL; - - snprintf(query, sizeof(query) - 1, SQL_GET_CHANNEL, ch->name); - - ret = flb_sqldb_query(db, query, winevtlog_sqlite_callback, &record); - if (ret == FLB_ERROR) { - return -1; - } - - if (record.created) { - ch->time_created = record.created; - } - if (record.time_updated) { - ch->time_updated = record.time_updated; - } - - if (record.name) { - bookmark_xml = convert_str(record.bookmark_xml); - if (bookmark_xml) { - bookmark = EvtCreateBookmark(bookmark_xml); - if (bookmark) { - /* re-create subscription handles */ - re_ch = winevtlog_subscribe(ch->name, FLB_FALSE, bookmark, ch->query); - if (re_ch != NULL) { - close_handles(ch); - - ch->bookmark = re_ch->bookmark; - ch->subscription = re_ch->subscription; - ch->signal_event = re_ch->signal_event; - } - else { - flb_error("Failed to subscribe with bookmark XML: %s\n", record.bookmark_xml); - ch->bookmark = EvtCreateBookmark(NULL); - } - } - else { - flb_error("Failed to load bookmark XML with %d\n", GetLastError()); - ch->bookmark = EvtCreateBookmark(NULL); - } - } - if (bookmark_xml) { - flb_free(bookmark_xml); - } - } - return 0; -} - -/* - * Save the bookmark into SQLite DB. - */ -int winevtlog_sqlite_save(struct winevtlog_channel *ch, struct flb_sqldb *db) -{ - int ret; - char query[1024]; - PWSTR wide_bookmark_xml = NULL; - char *bookmark_xml; - int used_size = 0; - - wide_bookmark_xml = render_event(ch->bookmark, EvtRenderBookmark, &used_size); - if (wide_bookmark_xml == NULL) { - flb_error("failed to render bookmark with %d", GetLastError()); - flb_free(wide_bookmark_xml); - - return -1; - } - bookmark_xml = convert_wstr(wide_bookmark_xml, CP_UTF8); - if (bookmark_xml == NULL) { - flb_error("failed to convert Wider string with %d", GetLastError()); - flb_free(wide_bookmark_xml); - flb_free(bookmark_xml); - - return -1; - } - - snprintf(query, sizeof(query) - 1, SQL_UPDATE_CHANNEL, - ch->name, bookmark_xml, ch->time_updated, time(NULL)); - - ret = flb_sqldb_query(db, query, NULL, NULL); - if (ret == FLB_ERROR) { - flb_error("failed to save db with %d", GetLastError()); - flb_free(wide_bookmark_xml); - flb_free(bookmark_xml); - - return -1; - } - - flb_free(wide_bookmark_xml); - flb_free(bookmark_xml); - - return 0; -} diff --git a/src/fluent-bit/plugins/in_winevtlog/winevtlog.h b/src/fluent-bit/plugins/in_winevtlog/winevtlog.h deleted file mode 100644 index 10ef3e457..000000000 --- a/src/fluent-bit/plugins/in_winevtlog/winevtlog.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -/* Fluent Bit - * ========== - * Copyright (C) 2019-2021 The Fluent Bit Authors - * Copyright (C) 2015-2018 Treasure Data Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FLB_WINEVTLOG_H -#define FLB_WINEVTLOG_H - -#include <winevt.h> -#include <fluent-bit/flb_log_event_encoder.h> - -struct winevtlog_config { - unsigned int interval_sec; - unsigned int interval_nsec; - unsigned int total_size_threshold; - int string_inserts; - int read_existing_events; - 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; - flb_pipefd_t coll_fd; - struct flb_input_instance *ins; - struct flb_log_event_encoder *log_encoder; -}; - -/* Some channels has very heavy contents for 10 events at same time. - * For now, we specify simultaneous subscribe size to 5. - */ -#define SUBSCRIBE_ARRAY_SIZE 5 - -struct winevtlog_channel { - EVT_HANDLE subscription; - EVT_HANDLE bookmark; - HANDLE signal_event; - EVT_HANDLE events[SUBSCRIBE_ARRAY_SIZE]; - int count; - - char *name; - char *query; - unsigned int time_updated; - unsigned int time_created; - struct mk_list _head; -}; - -struct winevtlog_sqlite_record { - char *name; - char *bookmark_xml; - unsigned int time_updated; - unsigned int created; -}; - -/* - * Open a Windows Event Log channel. - */ -struct winevtlog_channel *winevtlog_open(const char *channel); -void winevtlog_close(struct winevtlog_channel *ch); - -/* - * Read records from a channel. - */ -int winevtlog_read(struct winevtlog_channel *ch, - struct winevtlog_config *ctx, unsigned int *read); - -/* - * A bulk API to handle multiple channels at once using mk_list. - * - * "channels" are comma-separated names like "Setup,Security". - */ -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, - PEVT_VARIANT string_inserts, UINT count_inserts, struct winevtlog_channel *ch, - struct winevtlog_config *ctx); -void winevtlog_pack_event(PEVT_VARIANT system, WCHAR *message, - PEVT_VARIANT string_inserts, UINT count_inserts, struct winevtlog_channel *ch, - struct winevtlog_config *ctx); - -/* - * Save the read offset to disk. - */ -int winevtlog_sqlite_load(struct winevtlog_channel *ch, struct flb_sqldb *db); -int winevtlog_sqlite_save(struct winevtlog_channel *ch, struct flb_sqldb *db); - -/* - * SQL templates - */ -#define SQL_CREATE_CHANNELS \ - "CREATE TABLE IF NOT EXISTS in_winevtlog_channels (" \ - " name TEXT PRIMARY KEY," \ - " bookmark_xml TEXT," \ - " time_updated INTEGER," \ - " created INTEGER" \ - ");" - -#define SQL_GET_CHANNEL \ - "SELECT name, bookmark_xml, time_updated, created" \ - " FROM in_winevtlog_channels WHERE name = '%s';" - -/* - * This uses UPCERT i.e. execute INSERT first and fall back to - * UPDATE if the entry already exists. It saves the trouble of - * doing an existence check manually. - * - * https://www.sqlite.org/lang_UPSERT.html - */ -#define SQL_UPDATE_CHANNEL \ - "INSERT INTO in_winevtlog_channels" \ - " (name, bookmark_xml, time_updated, created)" \ - " VALUES ('%s', \"%s\", %u, %llu)" \ - " ON CONFLICT(name) DO UPDATE" \ - " SET bookmark_xml = excluded.bookmark_xml," \ - " time_updated = excluded.time_updated" \ - -#endif |