|
|
|
|
@ -77,14 +77,6 @@
|
|
|
|
|
#define LOG_HTTP_CF_CLIENT_PORT 'p'
|
|
|
|
|
#define LOG_HTTP_CF_SERVER_PORT 'P'
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
typedef struct LogHttpCustomFormatNode_ {
|
|
|
|
|
uint32_t type; /** Node format type. ie: LOG_HTTP_CF_LITERAL, LOG_HTTP_CF_REQUEST_HEADER */
|
|
|
|
|
uint32_t maxlen; /** Maximun length of the data */
|
|
|
|
|
char data[LOG_HTTP_NODE_STRLEN]; /** optional data. ie: http header name */
|
|
|
|
|
} LogHttpCustomFormatNode;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
typedef struct OutputHttpCtx_ {
|
|
|
|
|
uint32_t flags; /** Store mode */
|
|
|
|
|
} OutputHttpCtx;
|
|
|
|
|
@ -93,233 +85,6 @@ typedef struct OutputHttpCtx_ {
|
|
|
|
|
#define LOG_HTTP_EXTENDED 1
|
|
|
|
|
#define LOG_HTTP_CUSTOM 2
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
/* Retrieves the selected cookie value */
|
|
|
|
|
static uint32_t GetCookieValue(uint8_t *rawcookies, uint32_t rawcookies_len, char *cookiename,
|
|
|
|
|
uint8_t **cookievalue) {
|
|
|
|
|
uint8_t *p = rawcookies;
|
|
|
|
|
uint8_t *cn = p; /* ptr to cookie name start */
|
|
|
|
|
uint8_t *cv = NULL; /* ptr to cookie value start */
|
|
|
|
|
while (p < rawcookies + rawcookies_len) {
|
|
|
|
|
if (cv == NULL && *p == '=') {
|
|
|
|
|
cv = p + 1;
|
|
|
|
|
} else if (cv != NULL && (*p == ';' || p == rawcookies + rawcookies_len - 1) ) {
|
|
|
|
|
/* Found end of cookie */
|
|
|
|
|
p++;
|
|
|
|
|
if (strlen(cookiename) == (unsigned int) (cv-cn-1) &&
|
|
|
|
|
strncmp(cookiename, (char *) cn, cv-cn-1) == 0) {
|
|
|
|
|
*cookievalue = cv;
|
|
|
|
|
return (uint32_t) (p-cv);
|
|
|
|
|
}
|
|
|
|
|
cv = NULL;
|
|
|
|
|
cn = p + 1;
|
|
|
|
|
}
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Custom format logging */
|
|
|
|
|
static void LogHttpLogJSONCustom(AlertJsonThread *aft, json_t *js, htp_tx_t *tx, const struct timeval *ts /*,
|
|
|
|
|
char *srcip, Port sp, char *dstip, Port dp*/)
|
|
|
|
|
{
|
|
|
|
|
#if 0
|
|
|
|
|
LogHttpFileCtx *httplog_ctx = aft->httplog_ctx;
|
|
|
|
|
#endif
|
|
|
|
|
#if 0
|
|
|
|
|
uint32_t i;
|
|
|
|
|
uint32_t datalen;
|
|
|
|
|
char buf[128];
|
|
|
|
|
|
|
|
|
|
uint8_t *cvalue;
|
|
|
|
|
uint32_t cvalue_len = 0;
|
|
|
|
|
|
|
|
|
|
htp_header_t *h_request_hdr;
|
|
|
|
|
htp_header_t *h_response_hdr;
|
|
|
|
|
|
|
|
|
|
time_t time = ts->tv_sec;
|
|
|
|
|
struct tm local_tm;
|
|
|
|
|
struct tm *timestamp = SCLocalTime(time, &local_tm);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < httplog_ctx->cf_n; i++) {
|
|
|
|
|
h_request_hdr = NULL;
|
|
|
|
|
h_response_hdr = NULL;
|
|
|
|
|
switch (httplog_ctx->cf_nodes[i]->type){
|
|
|
|
|
case LOG_HTTP_CF_LITERAL:
|
|
|
|
|
/* LITERAL */
|
|
|
|
|
MemBufferWriteString(aft->buffer, "%s", httplog_ctx->cf_nodes[i]->data);
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_TIMESTAMP:
|
|
|
|
|
/* TIMESTAMP */
|
|
|
|
|
if (httplog_ctx->cf_nodes[i]->data[0] == '\0') {
|
|
|
|
|
strftime(buf, 62, TIMESTAMP_DEFAULT_FORMAT, timestamp);
|
|
|
|
|
} else {
|
|
|
|
|
strftime(buf, 62, httplog_ctx->cf_nodes[i]->data, timestamp);
|
|
|
|
|
}
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)buf,strlen(buf));
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_TIMESTAMP_U:
|
|
|
|
|
/* TIMESTAMP USECONDS */
|
|
|
|
|
snprintf(buf, 62, "%06u", (unsigned int) ts->tv_usec);
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)buf,strlen(buf));
|
|
|
|
|
break;
|
|
|
|
|
#ifdef NOTYET
|
|
|
|
|
case LOG_HTTP_CF_CLIENT_IP:
|
|
|
|
|
/* CLIENT IP ADDRESS */
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)srcip,strlen(srcip));
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_SERVER_IP:
|
|
|
|
|
/* SERVER IP ADDRESS */
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)dstip,strlen(dstip));
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_CLIENT_PORT:
|
|
|
|
|
/* CLIENT PORT */
|
|
|
|
|
MemBufferWriteString(aft->buffer, "%" PRIu16 "", sp);
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_SERVER_PORT:
|
|
|
|
|
/* SERVER PORT */
|
|
|
|
|
MemBufferWriteString(aft->buffer, "%" PRIu16 "", dp);
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_METHOD:
|
|
|
|
|
/* METHOD */
|
|
|
|
|
if (tx->request_method != NULL) {
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_method),
|
|
|
|
|
bstr_len(tx->request_method));
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_URI:
|
|
|
|
|
/* URI */
|
|
|
|
|
if (tx->request_uri != NULL) {
|
|
|
|
|
datalen = httplog_ctx->cf_nodes[i]->maxlen;
|
|
|
|
|
if (datalen == 0 || datalen > bstr_len(tx->request_uri)) {
|
|
|
|
|
datalen = bstr_len(tx->request_uri);
|
|
|
|
|
}
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_uri),
|
|
|
|
|
datalen);
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_HOST:
|
|
|
|
|
/* HOSTNAME */
|
|
|
|
|
if (tx->request_hostname != NULL)
|
|
|
|
|
{
|
|
|
|
|
datalen = httplog_ctx->cf_nodes[i]->maxlen;
|
|
|
|
|
if (datalen == 0 || datalen > bstr_len(tx->parsed_uri->hostname)) {
|
|
|
|
|
datalen = bstr_len(tx->parsed_uri->hostname);
|
|
|
|
|
}
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_hostname),
|
|
|
|
|
bstr_len(tx->request_hostname));
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_PROTOCOL:
|
|
|
|
|
/* PROTOCOL */
|
|
|
|
|
if (tx->request_protocol != NULL) {
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(tx->request_protocol),
|
|
|
|
|
bstr_len(tx->request_protocol));
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_HEADER:
|
|
|
|
|
/* REQUEST HEADER */
|
|
|
|
|
if (tx->request_headers != NULL) {
|
|
|
|
|
h_request_hdr = htp_table_get_c(tx->request_headers, httplog_ctx->cf_nodes[i]->data);
|
|
|
|
|
}
|
|
|
|
|
if (h_request_hdr != NULL) {
|
|
|
|
|
datalen = httplog_ctx->cf_nodes[i]->maxlen;
|
|
|
|
|
if (datalen == 0 || datalen > bstr_len(h_request_hdr->value)) {
|
|
|
|
|
datalen = bstr_len(h_request_hdr->value);
|
|
|
|
|
}
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(h_request_hdr->value),
|
|
|
|
|
datalen);
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_COOKIE:
|
|
|
|
|
/* REQUEST COOKIE */
|
|
|
|
|
if (tx->request_headers != NULL) {
|
|
|
|
|
h_request_hdr = htp_table_get_c(tx->request_headers, "Cookie");
|
|
|
|
|
if (h_request_hdr != NULL) {
|
|
|
|
|
cvalue_len = GetCookieValue((uint8_t *) bstr_ptr(h_request_hdr->value),
|
|
|
|
|
bstr_len(h_request_hdr->value), (char *) httplog_ctx->cf_nodes[i]->data,
|
|
|
|
|
&cvalue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (cvalue_len > 0) {
|
|
|
|
|
datalen = httplog_ctx->cf_nodes[i]->maxlen;
|
|
|
|
|
if (datalen == 0 || datalen > cvalue_len) {
|
|
|
|
|
datalen = cvalue_len;
|
|
|
|
|
}
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, cvalue, datalen);
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_REQUEST_LEN:
|
|
|
|
|
/* REQUEST LEN */
|
|
|
|
|
MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->request_message_len);
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_RESPONSE_STATUS:
|
|
|
|
|
/* RESPONSE STATUS */
|
|
|
|
|
if (tx->response_status != NULL) {
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(tx->response_status),
|
|
|
|
|
bstr_len(tx->response_status));
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_RESPONSE_HEADER:
|
|
|
|
|
/* RESPONSE HEADER */
|
|
|
|
|
if (tx->response_headers != NULL) {
|
|
|
|
|
h_response_hdr = htp_table_get_c(tx->response_headers,
|
|
|
|
|
httplog_ctx->cf_nodes[i]->data);
|
|
|
|
|
}
|
|
|
|
|
if (h_response_hdr != NULL) {
|
|
|
|
|
datalen = httplog_ctx->cf_nodes[i]->maxlen;
|
|
|
|
|
if (datalen == 0 || datalen > bstr_len(h_response_hdr->value)) {
|
|
|
|
|
datalen = bstr_len(h_response_hdr->value);
|
|
|
|
|
}
|
|
|
|
|
PrintRawUriBuf((char *)aft->buffer->buffer, &aft->buffer->offset,
|
|
|
|
|
aft->buffer->size, (uint8_t *)bstr_ptr(h_response_hdr->value),
|
|
|
|
|
datalen);
|
|
|
|
|
} else {
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LOG_HTTP_CF_RESPONSE_LEN:
|
|
|
|
|
/* RESPONSE LEN */
|
|
|
|
|
MemBufferWriteString(aft->buffer, "%"PRIuMAX"", (uintmax_t)tx->response_message_len);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* NO MATCH */
|
|
|
|
|
MemBufferWriteString(aft->buffer, LOG_HTTP_CF_NONE);
|
|
|
|
|
SCLogDebug("No matching parameter %%%c for custom http log.", httplog_ctx->cf_nodes[i]->type);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MemBufferWriteString(aft->buffer, "\n");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* JSON format logging */
|
|
|
|
|
static void LogHttpLogJSON(AlertJsonThread *aft, json_t *js, htp_tx_t *tx)
|
|
|
|
|
{
|
|
|
|
|
@ -457,7 +222,6 @@ static TmEcode HttpJsonIPWrapper(ThreadVars *tv, Packet *p, void *data, PacketQu
|
|
|
|
|
int tx_progress_done_value_tc = 0;
|
|
|
|
|
AlertJsonThread *aft = (AlertJsonThread *)data;
|
|
|
|
|
MemBuffer *buffer = (MemBuffer *)aft->buffer;
|
|
|
|
|
OutputHttpCtx *http_ctx = aft->http_ctx->data;
|
|
|
|
|
|
|
|
|
|
/* no flow, no htp state */
|
|
|
|
|
if (p->flow == NULL) {
|
|
|
|
|
|