Project

General

Profile

Feature #478 » 0003-XFF-support-for-alert-debuglog.patch

XFF support for alert-debug - Ignacio Sanchez, 08/07/2012 06:02 AM

View differences:

src/alert-debuglog.c
#include "util-debug.h"
#include "util-buffer.h"
#include "app-layer-htp.h"
#include "app-layer.h"
#include "output.h"
#include "alert-debuglog.h"
#include "util-privs.h"
......
OutputRegisterModule(MODULE_NAME, "alert-debug", AlertDebugLogInitCtx);
}
typedef struct AlertDebugLogThread_ {
#define ALERT_DEBUGLOG_XFF 1
#define ALERT_DEBUGLOG_XFF_OVERWRITE 2
#define ALERT_DEBUGLOG_XFF_DEFAULT "X-Forwarded-For"
#define ALERT_DEBUGLOG_XFF_MINLEN 7
typedef struct LogDebugFileCtx_ {
LogFileCtx *file_ctx;
uint32_t flags; /** Store mode */
char *xff_header; /** XFF Header name in case XFF mode is enabled */
} LogDebugFileCtx;
typedef struct AlertDebugLogThread_ {
LogDebugFileCtx *debuglog_ctx;
/** LogFileCtx has the pointer to the file and a mutex to allow multithreading */
MemBuffer *buffer;
} AlertDebugLogThread;
......
MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %"PRIu64"\n", p->pcap_cnt);
}
char srcip[46], dstip[46];
char srcip[46], dstip[46], xffip[128];
if (PKT_IS_IPV4(p)) {
PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip));
PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip));
} else if (PKT_IS_IPV6(p)) {
PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip));
PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip));
}
/* XFF Code */
if (aft->debuglog_ctx->flags & ALERT_DEBUGLOG_XFF) {
HtpState *htp_state = NULL;
htp_tx_t *tx = NULL;
htp_header_t *h_xff = NULL;
char *p_xff = NULL;
size_t idx = 0;
size_t hsize = 0;
if (p->flow && AppLayerGetProtoFromPacket(p) == ALPROTO_HTTP) {
htp_state = (HtpState *) AppLayerGetProtoStateFromPacket(p);
if ( htp_state && htp_state->connp && htp_state->connp->conn) {
hsize = list_size(htp_state->connp->conn->transactions);
for (idx = 0; idx < hsize; idx++) {
tx = list_get(htp_state->connp->conn->transactions, idx);
if (tx != NULL && tx->request_headers != NULL) {
h_xff = table_getc(tx->request_headers, aft->debuglog_ctx->xff_header);
if (h_xff != NULL && bstr_len(h_xff->value) > ALERT_DEBUGLOG_XFF_MINLEN - 1
&& bstr_len(h_xff->value) < 120) {
strlcpy(xffip, bstr_ptr(h_xff->value), bstr_len(h_xff->value) + 1);
/* Check for chained ips separated by ", ", we will get the last one */
p_xff = strrchr(xffip, ' ');
if (p_xff == NULL) {
p_xff = xffip;
} else {
p_xff++;
}
/* Sanity check on extracted IP */
if (strlen(p_xff) > ALERT_DEBUGLOG_XFF_MINLEN - 1 &&
strlen(p_xff) < 43 ) {
if (aft->debuglog_ctx->flags & ALERT_DEBUGLOG_XFF_OVERWRITE) {
strcpy(srcip, p_xff);
} else {
MemBufferWriteString(aft->buffer, "XFF IP: %s\n",
p_xff);
}
break;
}
}
}
}
}
}
}
MemBufferWriteString(aft->buffer, "SRC IP: %s\n"
......
}
}
SCMutexLock(&aft->file_ctx->fp_mutex);
MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp);
fflush(aft->file_ctx->fp);
aft->file_ctx->alerts += p->alerts.cnt;
SCMutexUnlock(&aft->file_ctx->fp_mutex);
SCMutexLock(&aft->debuglog_ctx->file_ctx->fp_mutex);
MemBufferPrintToFPAsString(aft->buffer, aft->debuglog_ctx->file_ctx->fp);
fflush(aft->debuglog_ctx->file_ctx->fp);
aft->debuglog_ctx->file_ctx->alerts += p->alerts.cnt;
SCMutexUnlock(&aft->debuglog_ctx->file_ctx->fp_mutex);
return TM_ECODE_OK;
}
......
PrintRawDataToBuffer(aft->buffer->buffer, &aft->buffer->offset, aft->buffer->size,
GET_PKT_DATA(p), GET_PKT_LEN(p));
SCMutexLock(&aft->file_ctx->fp_mutex);
MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp);
fflush(aft->file_ctx->fp);
aft->file_ctx->alerts += p->alerts.cnt;
SCMutexUnlock(&aft->file_ctx->fp_mutex);
SCMutexLock(&aft->debuglog_ctx->file_ctx->fp_mutex);
MemBufferPrintToFPAsString(aft->buffer, aft->debuglog_ctx->file_ctx->fp);
fflush(aft->debuglog_ctx->file_ctx->fp);
aft->debuglog_ctx->file_ctx->alerts += p->alerts.cnt;
SCMutexUnlock(&aft->debuglog_ctx->file_ctx->fp_mutex);
return TM_ECODE_OK;
}
......
return TM_ECODE_FAILED;
}
/** Use the Ouptut Context (file pointer and mutex) */
aft->file_ctx = ((OutputCtx *)initdata)->data;
aft->debuglog_ctx = ((OutputCtx *)initdata)->data;
/* 1 mb seems sufficient enough */
aft->buffer = MemBufferCreateNew(1 * 1024 * 1024);
......
return;
}
SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, aft->file_ctx->alerts);
SCLogInfo("(%s) Alerts %" PRIu64 "", tv->name, aft->debuglog_ctx->file_ctx->alerts);
}
static void AlertDebugLogDeInitCtx(OutputCtx *output_ctx)
{
if (output_ctx != NULL) {
LogFileCtx *logfile_ctx = (LogFileCtx *)output_ctx->data;
if (logfile_ctx != NULL) {
LogFileFreeCtx(logfile_ctx);
}
LogDebugFileCtx *debuglog_ctx = (LogDebugFileCtx *)output_ctx->data;
LogFileFreeCtx(debuglog_ctx->file_ctx);
SCFree(debuglog_ctx);
SCFree(output_ctx);
}
}
......
OutputCtx *AlertDebugLogInitCtx(ConfNode *conf)
{
LogFileCtx *file_ctx = NULL;
OutputCtx *output_ctx =NULL;
file_ctx = LogFileNewCtx();
if (file_ctx == NULL) {
......
goto error;
}
OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx));
output_ctx = SCMalloc(sizeof(OutputCtx));
if (output_ctx == NULL)
goto error;
LogDebugFileCtx *debuglog_ctx = SCMalloc(sizeof(LogDebugFileCtx));
if (debuglog_ctx == NULL) {
goto error;
}
memset(debuglog_ctx, 0x00, sizeof(LogDebugFileCtx));
debuglog_ctx->file_ctx = file_ctx;
memset(output_ctx, 0x00, sizeof(OutputCtx));
output_ctx->data = file_ctx;
output_ctx->data = debuglog_ctx;
output_ctx->DeInit = AlertDebugLogDeInitCtx;
const char *xff = ConfNodeLookupChildValue(conf, "xff");
const char *xff_header = ConfNodeLookupChildValue(conf, "xffheadername");
const char *xff_overwrite = ConfNodeLookupChildValue(conf, "xffoverwrite");
if (xff != NULL && ConfValIsTrue(xff)) {
debuglog_ctx->flags |= ALERT_DEBUGLOG_XFF;
if (xff_header != NULL) {
debuglog_ctx->xff_header = (char *) xff_header;
} else {
debuglog_ctx->xff_header = ALERT_DEBUGLOG_XFF_DEFAULT;
}
if (xff_overwrite != NULL && ConfValIsTrue(xff_overwrite)) {
debuglog_ctx->flags |= ALERT_DEBUGLOG_XFF_OVERWRITE;
}
}
SCLogDebug("Alert debug log output initialized");
return output_ctx;
......
if (file_ctx != NULL) {
LogFileFreeCtx(file_ctx);
}
if (output_ctx != NULL) {
SCFree(output_ctx);
}
return NULL;
}
(5-5/7)