/** * \brief Create a new LogFileCtx for "syslog" output style. * * \param conf The configuration node for this output. * \return A OutputCtx pointer on success, NULL on failure. */ OutputCtx *AlertSyslogInitCtx(ConfNode *conf) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } LogFileCtx *logfile_ctx = LogFileNewCtx(); if (logfile_ctx == NULL) { SCLogDebug("AlertSyslogInitCtx: Could not create new LogFileCtx"); return NULL; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { SCLogDebug("AlertSyslogInitCtx: Could not create new OutputCtx"); return NULL; } memset(output_ctx, 0x00, sizeof(OutputCtx)); output_ctx->data = logfile_ctx; output_ctx->DeInit = AlertSyslogDeInitCtx; SCLogInfo("Syslog output initialized"); return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputCtx *OutputJsonInitCtx(ConfNode *conf) { OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));; if (unlikely(json_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); return NULL; } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "type"); if (output_s != NULL) { if (strcmp(output_s, "file") == 0) { json_ctx->json_out = ALERT_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = ALERT_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = ALERT_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = ALERT_UNIX_STREAM; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } if (json_ctx->json_out == ALERT_FILE) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } const char *format_s = ConfNodeLookupChildValue(conf, "format"); if (format_s != NULL) { if (strcmp(format_s, "indent") == 0) { json_ctx->format = INDENT; } else if (strcmp(format_s, "compact") == 0) { json_ctx->format = COMPACT; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON format option: %s", format_s); exit(EXIT_FAILURE); } } } else if (json_out == ALERT_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-is: %s", sensor_id_s); exit(EXIT_FAILURE); } } format = json_ctx->format; json_out = json_ctx->json_out; } return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputCtx *OutputJsonInitCtx(ConfNode *conf) { OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx));; const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name"); if (unlikely(json_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); return NULL; } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return NULL; } if (sensor_name) { json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name); if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } } else { json_ctx->file_ctx->sensor_name = NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return NULL; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "filetype"); // Backwards compatibility if (output_s == NULL) { output_s = ConfNodeLookupChildValue(conf, "type"); } if (output_s != NULL) { if (strcmp(output_s, "file") == 0 || strcmp(output_s, "regular") == 0) { json_ctx->json_out = LOGFILE_TYPE_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = LOGFILE_TYPE_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_STREAM; } else if (strcmp(output_s, "redis") == 0) { #ifdef HAVE_LIBHIREDIS json_ctx->json_out = LOGFILE_TYPE_REDIS; #else SCLogError(SC_ERR_INVALID_ARGUMENT, "redis JSON output option is not compiled"); exit(EXIT_FAILURE); #endif } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } const char *prefix = ConfNodeLookupChildValue(conf, "prefix"); if (prefix != NULL) { SCLogInfo("Using prefix '%s' for JSON messages", prefix); json_ctx->file_ctx->prefix = SCStrdup(prefix); if (json_ctx->file_ctx->prefix == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for eve-log.prefix setting."); exit(EXIT_FAILURE); } json_ctx->file_ctx->prefix_len = strlen(prefix); } if (json_ctx->json_out == LOGFILE_TYPE_FILE || json_ctx->json_out == LOGFILE_TYPE_UNIX_DGRAM || json_ctx->json_out == LOGFILE_TYPE_UNIX_STREAM) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); const char *format_s = ConfNodeLookupChildValue(conf, "format"); if (format_s != NULL) { if (strcmp(format_s, "indent") == 0) { json_ctx->format = INDENT; } else if (strcmp(format_s, "compact") == 0) { json_ctx->format = COMPACT; } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON format option: %s", format_s); exit(EXIT_FAILURE); } } } else if (json_ctx->json_out == LOGFILE_TYPE_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { json_ctx->file_ctx->syslog_setup.alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } #ifdef HAVE_LIBHIREDIS else if (json_ctx->json_out == LOGFILE_TYPE_REDIS) { ConfNode *redis_node = ConfNodeLookupChild(conf, "redis"); if (!json_ctx->file_ctx->sensor_name) { char hostname[1024]; gethostname(hostname, 1023); json_ctx->file_ctx->sensor_name = SCStrdup(hostname); } if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return NULL; } } #endif const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-is: %s", sensor_id_s); exit(EXIT_FAILURE); } } json_ctx->file_ctx->type = json_ctx->json_out; } SCLogDebug("returning output_ctx %p", output_ctx); return output_ctx; }
/** * \brief Create a new LogFileCtx for "fast" output style. * \param conf The configuration node for this output. * \return A LogFileCtx pointer on success, NULL on failure. */ OutputInitResult OutputJsonInitCtx(ConfNode *conf) { OutputInitResult result = { NULL, false }; OutputJsonCtx *json_ctx = SCCalloc(1, sizeof(OutputJsonCtx)); if (unlikely(json_ctx == NULL)) { SCLogDebug("could not create new OutputJsonCtx"); return result; } /* First lookup a sensor-name value in this outputs configuration * node (deprecated). If that fails, lookup the global one. */ const char *sensor_name = ConfNodeLookupChildValue(conf, "sensor-name"); if (sensor_name != NULL) { SCLogWarning(SC_ERR_DEPRECATED_CONF, "Found deprecated eve-log setting \"sensor-name\". " "Please set sensor-name globally."); } else { (void)ConfGet("sensor-name", &sensor_name); } json_ctx->file_ctx = LogFileNewCtx(); if (unlikely(json_ctx->file_ctx == NULL)) { SCLogDebug("AlertJsonInitCtx: Could not create new LogFileCtx"); SCFree(json_ctx); return result; } if (sensor_name) { json_ctx->file_ctx->sensor_name = SCStrdup(sensor_name); if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return result; } } else { json_ctx->file_ctx->sensor_name = NULL; } OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); return result; } output_ctx->data = json_ctx; output_ctx->DeInit = OutputJsonDeInitCtx; if (conf) { const char *output_s = ConfNodeLookupChildValue(conf, "filetype"); // Backwards compatibility if (output_s == NULL) { output_s = ConfNodeLookupChildValue(conf, "type"); } if (output_s != NULL) { if (strcmp(output_s, "file") == 0 || strcmp(output_s, "regular") == 0) { json_ctx->json_out = LOGFILE_TYPE_FILE; } else if (strcmp(output_s, "syslog") == 0) { json_ctx->json_out = LOGFILE_TYPE_SYSLOG; } else if (strcmp(output_s, "unix_dgram") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_DGRAM; } else if (strcmp(output_s, "unix_stream") == 0) { json_ctx->json_out = LOGFILE_TYPE_UNIX_STREAM; } else if (strcmp(output_s, "redis") == 0) { #ifdef HAVE_LIBHIREDIS SCLogRedisInit(); json_ctx->json_out = LOGFILE_TYPE_REDIS; #else SCLogError(SC_ERR_INVALID_ARGUMENT, "redis JSON output option is not compiled"); exit(EXIT_FAILURE); #endif } else { SCLogError(SC_ERR_INVALID_ARGUMENT, "Invalid JSON output option: %s", output_s); exit(EXIT_FAILURE); } } const char *prefix = ConfNodeLookupChildValue(conf, "prefix"); if (prefix != NULL) { SCLogInfo("Using prefix '%s' for JSON messages", prefix); json_ctx->file_ctx->prefix = SCStrdup(prefix); if (json_ctx->file_ctx->prefix == NULL) { SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for eve-log.prefix setting."); exit(EXIT_FAILURE); } json_ctx->file_ctx->prefix_len = strlen(prefix); } if (json_ctx->json_out == LOGFILE_TYPE_FILE || json_ctx->json_out == LOGFILE_TYPE_UNIX_DGRAM || json_ctx->json_out == LOGFILE_TYPE_UNIX_STREAM) { if (SCConfLogOpenGeneric(conf, json_ctx->file_ctx, DEFAULT_LOG_FILENAME, 1) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return result; } OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); } #ifndef OS_WIN32 else if (json_ctx->json_out == LOGFILE_TYPE_SYSLOG) { const char *facility_s = ConfNodeLookupChildValue(conf, "facility"); if (facility_s == NULL) { facility_s = DEFAULT_ALERT_SYSLOG_FACILITY_STR; } int facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog facility: \"%s\"," " now using \"%s\" as syslog facility", facility_s, DEFAULT_ALERT_SYSLOG_FACILITY_STR); facility = DEFAULT_ALERT_SYSLOG_FACILITY; } const char *level_s = ConfNodeLookupChildValue(conf, "level"); if (level_s != NULL) { int level = SCMapEnumNameToValue(level_s, SCSyslogGetLogLevelMap()); if (level != -1) { json_ctx->file_ctx->syslog_setup.alert_syslog_level = level; } } const char *ident = ConfNodeLookupChildValue(conf, "identity"); /* if null we just pass that to openlog, which will then * figure it out by itself. */ openlog(ident, LOG_PID|LOG_NDELAY, facility); } #endif #ifdef HAVE_LIBHIREDIS else if (json_ctx->json_out == LOGFILE_TYPE_REDIS) { ConfNode *redis_node = ConfNodeLookupChild(conf, "redis"); if (!json_ctx->file_ctx->sensor_name) { char hostname[1024]; gethostname(hostname, 1023); json_ctx->file_ctx->sensor_name = SCStrdup(hostname); } if (json_ctx->file_ctx->sensor_name == NULL) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return result; } if (SCConfLogOpenRedis(redis_node, json_ctx->file_ctx) < 0) { LogFileFreeCtx(json_ctx->file_ctx); SCFree(json_ctx); SCFree(output_ctx); return result; } } #endif const char *sensor_id_s = ConfNodeLookupChildValue(conf, "sensor-id"); if (sensor_id_s != NULL) { if (ByteExtractStringUint64((uint64_t *)&sensor_id, 10, 0, sensor_id_s) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid sensor-id: %s", sensor_id_s); exit(EXIT_FAILURE); } } /* Check if top-level metadata should be logged. */ const ConfNode *metadata = ConfNodeLookupChild(conf, "metadata"); if (metadata && metadata->val && ConfValIsFalse(metadata->val)) { SCLogConfig("Disabling eve metadata logging."); json_ctx->cfg.include_metadata = false; } else { json_ctx->cfg.include_metadata = true; } /* See if we want to enable the community id */ const ConfNode *community_id = ConfNodeLookupChild(conf, "community-id"); if (community_id && community_id->val && ConfValIsTrue(community_id->val)) { SCLogConfig("Enabling eve community_id logging."); json_ctx->cfg.include_community_id = true; } else { json_ctx->cfg.include_community_id = false; } const char *cid_seed = ConfNodeLookupChildValue(conf, "community-id-seed"); if (cid_seed != NULL) { if (ByteExtractStringUint16(&json_ctx->cfg.community_id_seed, 10, 0, cid_seed) == -1) { SCLogError(SC_ERR_INVALID_ARGUMENT, "Failed to initialize JSON output, " "invalid community-id-seed: %s", cid_seed); exit(EXIT_FAILURE); } } /* Do we have a global eve xff configuration? */ const ConfNode *xff = ConfNodeLookupChild(conf, "xff"); if (xff != NULL) { json_ctx->xff_cfg = SCCalloc(1, sizeof(HttpXFFCfg)); if (likely(json_ctx->xff_cfg != NULL)) { HttpXFFGetCfg(conf, json_ctx->xff_cfg); } } const char *pcapfile_s = ConfNodeLookupChildValue(conf, "pcap-file"); if (pcapfile_s != NULL && ConfValIsTrue(pcapfile_s)) { json_ctx->file_ctx->is_pcap_offline = (RunmodeGetCurrent() == RUNMODE_PCAP_FILE); } json_ctx->file_ctx->type = json_ctx->json_out; } SCLogDebug("returning output_ctx %p", output_ctx); result.ctx = output_ctx; result.ok = true; return result; }