diff --git a/src/app-layer-irc.c b/src/app-layer-irc.c index 1826f4e6b58c..581ef3b7b1db 100644 --- a/src/app-layer-irc.c +++ b/src/app-layer-irc.c @@ -171,10 +171,21 @@ static IRCTransaction *IRCTransactionAlloc(IRCState *state, const uint16_t tx_id IRCTransaction *tx = SCMalloc(sizeof(IRCTransaction)); if (unlikely(tx == NULL)) return NULL; + //TODO: DNSIncrMemcap(sizeof(DNSTransaction), state); memset(tx, 0x00, sizeof(IRCTransaction)); tx->tx_num = tx_id; + tx->request = NULL; + tx->request_len = 0; + + tx->response = NULL; + tx->response_len = 0; + + tx->logged = 0; + tx->bad_cmd = 0; + + //tx->next = NULL; return tx; } @@ -184,8 +195,10 @@ static IRCTransaction *IRCTransactionAlloc(IRCState *state, const uint16_t tx_id static void IRCTransactionFree(IRCTransaction *tx, IRCState *state) { SCEnter(); - SCFree(tx->request); - SCFree(tx->response); + if (tx->request != NULL) + SCFree(tx->request); + if (tx->response != NULL) + SCFree(tx->response); //TODO: DNSDecrMemcap((sizeof(DNSQueryEntry) + q->len), state); @@ -222,7 +235,9 @@ static void IRCTransactionFree(IRCTransaction *tx, IRCState *state) DNSDecrMemcap(sizeof(DNSTransaction), state); */ - SCFree(tx); + if (tx != NULL) + SCFree(tx); + SCReturn; } @@ -270,7 +285,7 @@ static char * IRCCopyInput(uint8_t *input, uint32_t input_len) if (! input_len) return NULL; - char * ret = SCMalloc(input_len+1); + char * ret = SCMalloc(input_len + 1); if (!ret) return NULL; @@ -281,28 +296,61 @@ static char * IRCCopyInput(uint8_t *input, uint32_t input_len) return ret; } +/** \brief Function to parse IRC client command . + * + * \param input - + * \param input_len - + * \param cmd_len - + */ +static char * IRCParseCommandAlloc(uint8_t *input, uint32_t input_len, uint32_t* cmd_len) +{ + char * cmd = NULL; + uint32_t command_size = IRCParseCommandEndOffset(input, input_len); + + *cmd_len = command_size; + if (! command_size) { + return cmd; + } + + cmd = SCMalloc(command_size + 1); + if (unlikely(cmd == NULL)) { + return NULL; + } + + memset(cmd, 0, command_size + 1); + memcpy(cmd, input, command_size); + + return cmd; + +} + /** \brief Function to parse IRC client command request */ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, void *local_data) { + + SCEnter(); + +#ifdef DEBUG + AppLayerParserStatePrintDetails(pstate); char * cpy = IRCCopyInput(input, input_len); if (cpy) { - SCLogInfo("IRC = REQ :[%s]", cpy); + SCLogDebug("IRC = REQ :[%s]", cpy); SCFree(cpy); } else { - SCLogInfo("IRC = REQ :[%s]", ""); + SCLogDebug("IRC = REQ :[%s]", ""); } - SCEnter(); if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCLogInfo("IRC = REQ NULL AND EOF "); + SCLogDebug("IRC = REQ NULL AND EOF "); SCReturnInt(1); } else if (input == NULL || input_len == 0) { - SCLogInfo("IRC = REQ NULL OR EMPTY "); + SCLogDebug("IRC = REQ NULL OR EMPTY "); SCReturnInt(-1); } +#endif IRCState *irc_state = (IRCState *)state; if (irc_state == NULL) { @@ -318,12 +366,13 @@ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, } irc_state->transaction_max++; - TAILQ_INSERT_TAIL(&irc_state->tx_list, tx, next); //TODO: dns_state->curr = tx; - SCLogInfo("IRC = new tx with internal num %u", tx->tx_num); + SCLogDebug("IRC = new tx with internal num %u", tx->tx_num); + //TODO: dns_state->unreplied_cnt++; + uint32_t command_size = 0; + char * cmd = IRCParseCommandAlloc(input, input_len, &command_size); - uint32_t command_size = IRCParseCommandEndOffset(input, input_len); if (command_size == 4) { int is_nick = 0; int is_user = 0; @@ -372,17 +421,14 @@ static int IRCParseRequest(Flow *f, void *state, AppLayerParserState *pstate, } end: + /* Insert transaction in queue*/ if (tx != NULL) { - tx->request = SCMalloc(input_len) + 1; - memset(tx->request, 0, input_len+1); + tx->cmd = cmd; tx->request_len = input_len; - if (tx->request) { - memcpy(tx->request, input, input_len); - SCLogInfo("IRC REQUEST INPUT: %s [%d]", tx->request, tx->request_len); - TAILQ_INSERT_TAIL(&irc_state->tx_list, tx, next); - } else { - IRCTransactionFree(tx, irc_state); - } + tx->request = IRCCopyInput(input, input_len); + SCLogInfo("IRC REQUEST TXLIST:[%p] CMD:[%s] INPUT:[%s] LEN:[%d] ", + &irc_state->tx_list, tx->cmd, tx->request, tx->request_len); + TAILQ_INSERT_TAIL(&irc_state->tx_list, tx, next); } SCReturnInt(1); } @@ -395,44 +441,39 @@ static int IRCParseResponse(Flow *f, void *state, AppLayerParserState *pstate, { SCEnter(); +#ifdef DEBUG + AppLayerParserStatePrintDetails(pstate); + char * cpy = IRCCopyInput(input, input_len); if (cpy) { - SCLogInfo("IRC = RSP :[%s]", cpy); + SCLogDebug("IRC = RSP :[%s]", cpy); SCFree(cpy); } else { - SCLogInfo("IRC = RSP :[%s]", ""); + SCLogDebug("IRC = RSP :[%s]", ""); } if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) { - SCLogInfo("IRC = RSP NULL AND EOF "); + SCLogDebug("IRC = RSP NULL AND EOF "); SCReturnInt(1); } else if (input == NULL || input_len == 0) { - SCLogInfo("IRC = RSP INPUT NULL OR EMPTY "); + SCLogDebug("IRC = RSP INPUT NULL OR EMPTY "); SCReturnInt(-1); } +#endif IRCState *irc_state = (IRCState *)state; if (irc_state == NULL) { SCReturnInt(-1); } -// # define TAILQ_HEAD(name, type) \ -//struct name { \ -// struct type *tqh_first; /* first element */ \ -// struct type **tqh_last; /* addr of last next element */ \ -//} -// # define TAILQ_LAST(head, headname) \ -// (*(((struct headname *)((head)->tqh_last))->tqh_last)) - //IRCTransaction *tx = TAILQ_LAST( irc_state->tx_list, IRCTransaction_); - IRCTransaction *tx = (IRCTransaction *) *(&irc_state->tx_list.tqh_last); + IRCTransaction *tx = TAILQ_LAST(&irc_state->tx_list, _list); if (tx) { -// tx->response = SCMalloc(input_len) + 1; -// memset(tx->response, 0, input_len+1); -// tx->response_len = input_len; -// if (tx->response) { -// memcpy(tx->response, input, input_len); -// SCLogInfo("TX=%d, IRC RESPONSE INPUT: %s [%d]", tx->tx_num, tx->response, tx->response_len); -// } + + /* Update response on last transaction */ + tx->response_len = input_len; + tx->response = IRCCopyInput(input, input_len); + SCLogInfo("TX=%d, IRC RESPONSE INPUT: %s [%d]", tx->tx_num, tx->response, tx->response_len); + } else { SCLogInfo("IRC : Failed to get last transaction"); } @@ -533,9 +574,10 @@ static void *IRCStateAlloc(void) st->cli.num_bad_cmds = 0; st->srv.hostname = NULL; st->transaction_max = 0 ; - TAILQ_INIT(&st->tx_list); + SCLogInfo("TX LIST=%p", &st->tx_list); + return s; } @@ -579,6 +621,7 @@ int IRCGetAlstateProgress(void *tx, uint8_t direction) // * a tx it we consider the request complete. */ // return 1; // } + SCLogInfo("IRCGetAlstateProgress"); return 0; //1; } @@ -588,7 +631,8 @@ int IRCGetAlstateProgress(void *tx, uint8_t direction) int IRCGetAlstateProgressCompletionStatus(uint8_t direction) { //TODO: to check if quit was requested or responded - return 0; // 1 + SCLogInfo("IRCGetAlstateProgressCompletionStatus"); + return 1; // 1 } static int IRCRegisterPatternsForProtocolDetection(void) @@ -645,8 +689,8 @@ void RegisterIRCParsers(void) AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_IRC, IRCGetTx); AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_IRC, IRCGetTxCnt); AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_IRC, IRCGetTxLogged, IRCSetTxLogged); - //AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_IRC, IRCGetAlstateProgress); - //AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_IRC, IRCGetAlstateProgressCompletionStatus); + AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_IRC, IRCGetAlstateProgress); + AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_IRC, IRCGetAlstateProgressCompletionStatus); } else { SCLogInfo("Parsed disabled for %s protocol. Protocol detection" "still on.", proto_name); diff --git a/src/app-layer-irc.h b/src/app-layer-irc.h index b3681de4554b..74a60081392e 100644 --- a/src/app-layer-irc.h +++ b/src/app-layer-irc.h @@ -38,10 +38,12 @@ typedef struct IRCServer_ { typedef struct IRCTransaction_ { uint16_t tx_num; /**< internal: id */ - uint8_t *request; + char *cmd; + + char *request; uint8_t request_len; - uint8_t *response; + char *response; uint8_t response_len; uint32_t logged; /**< flags for loggers done logging */ @@ -54,7 +56,7 @@ typedef struct IRCTransaction_ { typedef struct IRCState_ { IRCServer srv; IRCClient cli; - TAILQ_HEAD(list, IRCTransaction_) tx_list; /**< transaction list */ + TAILQ_HEAD(_list, IRCTransaction_) tx_list; /**< transaction list */ uint64_t transaction_max; } IRCState; diff --git a/src/log-irclog.c b/src/log-irclog.c index ff74cc8768c0..5488236ebbe8 100644 --- a/src/log-irclog.c +++ b/src/log-irclog.c @@ -24,11 +24,14 @@ */ #include "suricata-common.h" -#include "util-print.h" #include "output.h" #include "log-irclog.h" + #include "app-layer-parser.h" +#include "app-layer-irc.h" + #include "util-logopenfile.h" +#include "util-print.h" #define DEFAULT_LOG_FILENAME "irc.log" #define MODULE_NAME "LogIrcLog" @@ -41,16 +44,12 @@ typedef struct LogIrcFileCtx_ { typedef struct LogIrcLogThread_ { LogIrcFileCtx *irclog_ctx; /** LogFileCtx has the pointer to the file and a mutex to allow multithreading */ - uint32_t cmds_cnt; - MemBuffer *buffer; } LogIrcLogThread; int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *state, void *tx, uint64_t tx_id) { - SCLogInfo (" ----------- LOG: IRC -------------------- "); - SCEnter(); if (!(PKT_IS_TCP(p))) { @@ -59,6 +58,7 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta LogIrcLogThread *aft = (LogIrcLogThread *)data; LogIrcFileCtx *irclog = aft->irclog_ctx; + IRCTransaction *irctx = (IRCTransaction *) tx; int ipproto = PKT_IS_IPV4(p) ? AF_INET: AF_INET6; char srcip[46], dstip[46]; @@ -95,18 +95,19 @@ int LogIrcLogger(ThreadVars *tv, void *data, const Packet *p, Flow *f, void *sta dp = p->sp; } - MemBufferWriteString(aft->buffer, - " [**][**] %s:%" PRIu16 " -> %s:%" PRIu16 "\n", - srcip, sp, dstip, dp); + SCLogInfo( "[**][**] %s:%" PRIu16 " -> %s:%" PRIu16 " %lu: [%s] [%s] - [%s] \n", + srcip, sp, dstip, dp, tx_id, irctx->cmd, irctx->request, irctx->response); + + MemBufferWriteString( aft->buffer, "[**][**] %s:%" PRIu16 " -> %s:%" PRIu16 " %lu: [%s] [%s] - [%s] \n", + srcip, sp, dstip, dp, tx_id, irctx->cmd, irctx->request, irctx->response); SCMutexLock(&irclog->file_ctx->fp_mutex); irclog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), MEMBUFFER_OFFSET(aft->buffer), irclog->file_ctx); SCMutexUnlock(&irclog->file_ctx->fp_mutex); - SCReturnInt(0); end: - SCReturnInt(-1); + SCReturnInt(TM_ECODE_OK); } @@ -201,9 +202,7 @@ OutputCtx *LogIrcLogInitCtx(ConfNode *conf) SCLogDebug("IRC log output initialized"); /* enable the logger for the app layer */ - SCLogInfo("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); AppLayerParserRegisterLogger(IPPROTO_TCP, ALPROTO_IRC); - SCLogInfo("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); return output_ctx; } diff --git a/suricata.yaml.in b/suricata.yaml.in index a81fad71114d..233e30b02ee4 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -709,6 +709,8 @@ app-layer: enabled: detection-only msn: enabled: detection-only + irc: + enabled: no smb: enabled: yes detection-ports: