diff --git a/src/alert-syslog.c b/src/alert-syslog.c index f94470ec99..5c5e5119d5 100644 --- a/src/alert-syslog.c +++ b/src/alert-syslog.c @@ -54,6 +54,8 @@ #define DEFAULT_ALERT_SYSLOG_LEVEL LOG_ERR #define MODULE_NAME "AlertSyslog" +static int alert_syslog_level = DEFAULT_ALERT_SYSLOG_LEVEL; + typedef struct AlertSyslogThread_ { /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ LogFileCtx* file_ctx; @@ -111,7 +113,7 @@ void TmModuleAlertSyslogIPv6Register (void) { OutputCtx *AlertSyslogInitCtx(ConfNode *conf) { const char *enabled = ConfNodeLookupChildValue(conf, "enabled"); - if (enabled != NULL && strncmp(enabled, "no", 2) == 0) { + if (enabled != NULL && strcasecmp(enabled, "no") == 0) { SCLogDebug("alert-syslog module has been disabled"); return NULL; } @@ -127,7 +129,7 @@ OutputCtx *AlertSyslogInitCtx(ConfNode *conf) return NULL; } - int facility = SCMapEnumNameToValue(facility_s, SCGetFacilityMap()); + 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, @@ -135,13 +137,22 @@ OutputCtx *AlertSyslogInitCtx(ConfNode *conf) 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; + } + } + openlog(NULL, LOG_NDELAY, facility); - OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); + OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx)); if (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; @@ -161,7 +172,9 @@ static void AlertSyslogDeInitCtx(OutputCtx *output_ctx) { if (output_ctx != NULL) { LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data; - LogFileFreeCtx(logfile_ctx); + if (logfile_ctx != NULL) { + LogFileFreeCtx(logfile_ctx); + } free(output_ctx); } closelog(); @@ -177,18 +190,18 @@ static void AlertSyslogDeInitCtx(OutputCtx *output_ctx) */ TmEcode AlertSyslogThreadInit(ThreadVars *t, void *initdata, void **data) { + if(initdata == NULL) { + SCLogDebug("Error getting context for AlertSyslog. \"initdata\" " + "argument NULL"); + return TM_ECODE_FAILED; + } + AlertSyslogThread *ast = SCMalloc(sizeof(AlertSyslogThread)); if (ast == NULL) return TM_ECODE_FAILED; memset(ast, 0, sizeof(AlertSyslogThread)); - if(initdata == NULL) - { - SCLogDebug("Error getting context for AlertSyslog. \"initdata\" " - "argument NULL"); - SCFree(ast); - return TM_ECODE_FAILED; - } + /** Use the Ouptut Context (file pointer and mutex) */ ast->file_ctx = ((OutputCtx *)initdata)->data; @@ -249,13 +262,13 @@ TmEcode AlertSyslogIPv4(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); if (SCProtoNameValid(IPV4_GET_IPPROTO(p)) == TRUE) { - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "[%" PRIu32 ":%" PRIu32 ":%" + syslog(alert_syslog_level, "[%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [Classification: %s] [Priority: %"PRIu32"]" " {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "", pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio, known_proto[IPV4_GET_IPPROTO(p)], srcip, p->sp, dstip, p->dp); } else { - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "[%" PRIu32 ":%" PRIu32 ":%" + syslog(alert_syslog_level, "[%" PRIu32 ":%" PRIu32 ":%" PRIu32 "] %s [Classification: %s] [Priority: %"PRIu32"]" " {PROTO:%03" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "", pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio, @@ -299,7 +312,7 @@ TmEcode AlertSyslogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, inet_ntop(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); if (SCProtoNameValid(IPV6_GET_L4PROTO(p)) == TRUE) { - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "[%" PRIu32 ":%" PRIu32 ":%" + syslog(alert_syslog_level, "[%" PRIu32 ":%" PRIu32 ":%" "" PRIu32 "] %s [Classification: %s] [Priority: %" "" PRIu32 "] {%s} %s:%" PRIu32 " -> %s:%" PRIu32 "", pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, @@ -307,7 +320,7 @@ TmEcode AlertSyslogIPv6(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, dstip, p->dp); } else { - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "[%" PRIu32 ":%" PRIu32 ":%" + syslog(alert_syslog_level, "[%" PRIu32 ":%" PRIu32 ":%" "" PRIu32 "] %s [Classification: %s] [Priority: %" "" PRIu32 "] {PROTO:%03" PRIu32 "} %s:%" PRIu32 " -> %s:%" PRIu32 "", pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, @@ -343,23 +356,33 @@ TmEcode AlertSyslogDecoderEvent(ThreadVars *tv, Packet *p, void *data, SCMutexLock(&ast->file_ctx->fp_mutex); ast->file_ctx->alerts += p->alerts.cnt; - char temp_buf[2048]; + char temp_buf_hdr[512]; + char temp_buf_pkt[65] = ""; + char temp_buf_tail[32]; + char alert[2048] = ""; for (i = 0; i < p->alerts.cnt; i++) { PacketAlert *pa = &p->alerts.alerts[i]; - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "[%" PRIu32 ":%" PRIu32 ":%" PRIu32 "]" - " %s [Classification: %s] [Priority: %" PRIu32 "] [**] [Raw pkt: ", - pa->gid, pa->sid, pa->rev, pa->msg, pa->class_msg, pa->prio); + snprintf(temp_buf_hdr, sizeof(temp_buf_hdr), "[%" PRIu32 ":%" PRIu32 + ":%" PRIu32 "] %s [Classification: %s] [Priority: %" PRIu32 + "] [**] [Raw pkt: ", pa->gid, pa->sid, pa->rev, pa->msg, + pa->class_msg, pa->prio); + strlcpy(alert, temp_buf_hdr, sizeof(alert)); - PrintRawLineHexBuf(temp_buf, p->pkt, p->pktlen < 32 ? p->pktlen : 32); - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "%s", temp_buf); + PrintRawLineHexBuf(temp_buf_pkt, sizeof(temp_buf_pkt), p->pkt, p->pktlen < 32 ? p->pktlen : 32); + strlcat(alert, temp_buf_pkt, sizeof(alert)); if (p->pcap_cnt != 0) { - syslog(DEFAULT_ALERT_SYSLOG_LEVEL, "] [pcap file packet: %"PRIu64"]", + snprintf(temp_buf_tail, sizeof(temp_buf_tail), "] [pcap file packet: %"PRIu64"]", p->pcap_cnt); + } else { + temp_buf_tail[0] = ']'; + temp_buf_tail[1] = '\0'; } + strlcat(alert, temp_buf_tail, sizeof(alert)); + syslog(alert_syslog_level, "%s", alert); } SCMutexUnlock(&ast->file_ctx->fp_mutex); @@ -381,11 +404,11 @@ TmEcode AlertSyslog (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq) { if (PKT_IS_IPV4(p)) { - return AlertSyslogIPv4(tv, p, data, pq, postpq); + return AlertSyslogIPv4(tv, p, data, pq, NULL); } else if (PKT_IS_IPV6(p)) { - return AlertSyslogIPv6(tv, p, data, pq, postpq); + return AlertSyslogIPv6(tv, p, data, pq, NULL); } else if (p->events.cnt > 0) { - return AlertSyslogDecoderEvent(tv, p, data, pq, postpq); + return AlertSyslogDecoderEvent(tv, p, data, pq, NULL); } return TM_ECODE_OK; @@ -404,4 +427,5 @@ void AlertSyslogExitPrintStats(ThreadVars *tv, void *data) { } SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, ast->file_ctx->alerts); -} \ No newline at end of file +} + diff --git a/src/alert-syslog.h b/src/alert-syslog.h index 440009c742..14f7740449 100644 --- a/src/alert-syslog.h +++ b/src/alert-syslog.h @@ -24,11 +24,12 @@ * */ -#ifndef ALERT_SYSLOG_H -#define ALERT_SYSLOG_H +#ifndef __ALERT_SYSLOG_H__ +#define __ALERT_SYSLOG_H__ void TmModuleAlertSyslogRegister (void); void TmModuleAlertSyslogIPv4Register (void); void TmModuleAlertSyslogIPv6Register (void); -#endif /* ALERT_SYSLOG_H */ +#endif /* __ALERT_SYSLOG_H__ */ + diff --git a/src/util-debug.c b/src/util-debug.c index c55b5ba39b..837f8765c9 100644 --- a/src/util-debug.c +++ b/src/util-debug.c @@ -857,7 +857,7 @@ static inline void SCLogSetOPIface(SCLogInitData *sc_lid, SCLogConfig *sc_lc) if (s == NULL) s = SC_LOG_DEF_SYSLOG_FACILITY_STR; - op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCGetFacilityMap()), NULL, -1); + op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1); break; default: break; @@ -1047,7 +1047,7 @@ SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name, case SC_LOG_OP_IFACE_FILE: return SCLogInitFileOPIface(arg, log_format, log_level); case SC_LOG_OP_IFACE_SYSLOG: - return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCGetFacilityMap()), log_format, log_level); + return SCLogInitSyslogOPIface(SCMapEnumNameToValue(arg, SCSyslogGetFacilityMap()), log_format, log_level); default: #ifdef DEBUG printf("Output Interface \"%s\" not supported by the logging module", @@ -1183,7 +1183,7 @@ void SCLogLoadConfig(void) const char *facility_s = ConfNodeLookupChildValue(output, "facility"); if (facility_s != NULL) { - facility = SCMapEnumNameToValue(facility_s, SCGetFacilityMap()); + facility = SCMapEnumNameToValue(facility_s, SCSyslogGetFacilityMap()); if (facility == -1) { SCLogWarning(SC_ERR_INVALID_ARGUMENT, "Invalid syslog " "facility: \"%s\", now using \"%s\" as syslog " @@ -1270,7 +1270,7 @@ void SCLogInitLogModuleIfEnvSet(void) if (s == NULL) s = SC_LOG_DEF_SYSLOG_FACILITY_STR; - op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCGetFacilityMap()), NULL, -1); + op_ifaces_ctx = SCLogInitSyslogOPIface(SCMapEnumNameToValue(s, SCSyslogGetFacilityMap()), NULL, -1); break; default: break; diff --git a/src/util-print.c b/src/util-print.c index d49125cc91..e2d78de8fe 100644 --- a/src/util-print.c +++ b/src/util-print.c @@ -55,17 +55,21 @@ void PrintRawLineHexFp(FILE *fp, uint8_t *buf, uint32_t buflen) * Prints in the format "00 AA BB" * * \param retbuf pointer to the buffer which will have the result + * \param rebuflen lenght of the buffer * \param buf buffer to print from * \param buflen length of the input buffer */ -void PrintRawLineHexBuf(char *retbuf, uint8_t *buf, uint32_t buflen) +void PrintRawLineHexBuf(char *retbuf, uint32_t retbuflen, uint8_t *buf, uint32_t buflen) { char temp[5] = ""; uint32_t u = 0; + uint32_t written = 0; for (u = 0; u < buflen; u++) { - snprintf(temp, sizeof(temp), "%02X ", buf[u]); - strlcat(retbuf, temp, sizeof(retbuf)); + written += (uint32_t)snprintf(temp, sizeof(temp), "%02X ", buf[u]); + if (written < retbuflen) { + strlcat(retbuf, temp, sizeof(retbuf)); + } } } diff --git a/src/util-print.h b/src/util-print.h index 5eb99d30dc..ad005e4a16 100644 --- a/src/util-print.h +++ b/src/util-print.h @@ -27,7 +27,7 @@ void PrintRawLineHexFp(FILE *, uint8_t *, uint32_t); void PrintRawUriFp(FILE *, uint8_t *, uint32_t); void PrintRawDataFp(FILE *, uint8_t *, uint32_t); -void PrintRawLineHexBuf(char *, uint8_t *, uint32_t ); +void PrintRawLineHexBuf(char *, uint32_t, uint8_t *, uint32_t ); #endif /* __UTIL_PRINT_H__ */ diff --git a/src/util-syslog.c b/src/util-syslog.c index ff6148c785..d2bf3b6b23 100644 --- a/src/util-syslog.c +++ b/src/util-syslog.c @@ -53,6 +53,24 @@ SCEnumCharMap sc_syslog_facility_map[] = { }; /** \brief returns the syslog facility enum map */ -SCEnumCharMap *SCGetFacilityMap() { +SCEnumCharMap *SCSyslogGetFacilityMap() { return sc_syslog_facility_map; } + +SCEnumCharMap sc_syslog_level_map[ ] = { + { "Emergency", LOG_EMERG }, + { "Alert", LOG_ALERT }, + { "Critical", LOG_CRIT }, + { "Error", LOG_ERR }, + { "Warning", LOG_WARNING }, + { "Notice", LOG_NOTICE }, + { "Info", LOG_INFO }, + { "Debug", LOG_DEBUG }, + { NULL, -1 } +}; + +/** \brief returns the syslog facility enum map */ +SCEnumCharMap *SCSyslogGetLogLevelMap() { + return sc_syslog_level_map; +} + diff --git a/src/util-syslog.h b/src/util-syslog.h index ae7d0b7e55..0efc1c5db7 100644 --- a/src/util-syslog.h +++ b/src/util-syslog.h @@ -25,6 +25,7 @@ #ifndef UTIL_SYSLOG_H #define UTIL_SYSLOG_H -SCEnumCharMap *SCGetFacilityMap(void); +SCEnumCharMap *SCSyslogGetFacilityMap(void); +SCEnumCharMap *SCSyslogGetLogLevelMap(void); #endif /* UTIL_SYSLOG_H */ diff --git a/suricata.yaml b/suricata.yaml index 9b658f5923..4a55ceb9f2 100644 --- a/suricata.yaml +++ b/suricata.yaml @@ -100,6 +100,8 @@ outputs: - syslog: enabled: no facility: local5 + #level: Info ## possible levels: Emergency, Alert, Critical, + ## Error, Warning, Notice, Info, Debug # When running in NFQ inline mode, it is possible to use a simulated # non-terminal NFQUEUE verdict.