diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index 974ec2e561..7bdd404369 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -303,6 +303,13 @@ static void FTPStateFree(void *s) SCFree(fstate->line_state[0].db); if (fstate->line_state[1].db) SCFree(fstate->line_state[1].db); + + //AppLayerDecoderEventsFreeEvents(&s->decoder_events); + + if (fstate->de_state != NULL) { + DetectEngineStateFree(fstate->de_state); + } + SCFree(s); #ifdef DEBUG SCMutexLock(&ftp_state_mem_lock); @@ -312,6 +319,64 @@ static void FTPStateFree(void *s) #endif } +static int FTPStateHasTxDetectState(void *state) +{ + FtpState *ssh_state = (FtpState *)state; + if (ssh_state->de_state) + return 1; + return 0; +} + +static int FTPSetTxDetectState(void *state, void *vtx, DetectEngineState *de_state) +{ + FtpState *ssh_state = (FtpState *)state; + ssh_state->de_state = de_state; + return 0; +} + +static DetectEngineState *FTPGetTxDetectState(void *vtx) +{ + FtpState *ssh_state = (FtpState *)vtx; + return ssh_state->de_state; +} + +static void FTPStateTransactionFree(void *state, uint64_t tx_id) +{ + /* do nothing */ +} + +static void *FTPGetTx(void *state, uint64_t tx_id) +{ + FtpState *ssh_state = (FtpState *)state; + return ssh_state; +} + +static uint64_t FTPGetTxCnt(void *state) +{ + /* single tx */ + return 1; +} + +static int FTPGetAlstateProgressCompletionStatus(uint8_t direction) +{ + return FTP_STATE_FINISHED; +} + +static int FTPGetAlstateProgress(void *tx, uint8_t direction) +{ + FtpState *ftp_state = (FtpState *)tx; + + if (direction == STREAM_TOSERVER && + ftp_state->command == FTP_COMMAND_PORT) { + return FTP_STATE_PORT_DONE; + } + + /* TODO: figure out further progress handling */ + + return FTP_STATE_IN_PROGRESS; +} + + static int FTPRegisterPatternsForProtocolDetection(void) { if (AppLayerProtoDetectPMRegisterPatternCI(IPPROTO_TCP, ALPROTO_FTP, @@ -351,6 +416,20 @@ void RegisterFTPParsers(void) FTPParseResponse); AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_FTP, FTPStateAlloc, FTPStateFree); AppLayerParserRegisterParserAcceptableDataDirection(IPPROTO_TCP, ALPROTO_FTP, STREAM_TOSERVER | STREAM_TOCLIENT); + + AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_FTP, FTPStateTransactionFree); + + AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_FTP, FTPStateHasTxDetectState, + FTPGetTxDetectState, FTPSetTxDetectState); + + AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_FTP, FTPGetTx); + + AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_FTP, FTPGetTxCnt); + + AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_FTP, FTPGetAlstateProgress); + + AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_FTP, + FTPGetAlstateProgressCompletionStatus); } else { SCLogInfo("Parsed disabled for %s protocol. Protocol detection" "still on.", proto_name); diff --git a/src/app-layer-ftp.h b/src/app-layer-ftp.h index 4a001290d5..de93f5f773 100644 --- a/src/app-layer-ftp.h +++ b/src/app-layer-ftp.h @@ -24,6 +24,12 @@ #ifndef __APP_LAYER_FTP_H__ #define __APP_LAYER_FTP_H__ +enum { + FTP_STATE_IN_PROGRESS, + FTP_STATE_PORT_DONE, + FTP_STATE_FINISHED, +}; + typedef enum { FTP_COMMAND_UNKNOWN = 0, FTP_COMMAND_ABOR, @@ -123,6 +129,11 @@ typedef struct FtpState_ { uint32_t port_line_len; uint32_t port_line_size; uint8_t *port_line; + + /* specifies which loggers are done logging */ + uint32_t logged; + + DetectEngineState *de_state; } FtpState; void RegisterFTPParsers(void); diff --git a/src/detect-ftpbounce.c b/src/detect-ftpbounce.c index 7895c854fb..0e2c2a07b5 100644 --- a/src/detect-ftpbounce.c +++ b/src/detect-ftpbounce.c @@ -47,13 +47,19 @@ #include "stream-tcp.h" #include "util-byte.h" -static int DetectFtpbounceALMatch(ThreadVars *, DetectEngineThreadCtx *, Flow *, - uint8_t, void *, const Signature *, const SigMatchData *); +static int DetectFtpbounceALMatch(ThreadVars *, DetectEngineThreadCtx *, + Flow *, uint8_t, void *, void *, + const Signature *, const SigMatchCtx *); + static int DetectFtpbounceSetup(DetectEngineCtx *, Signature *, char *); -static int DetectFtpbounceMatchArgs(uint8_t *payload, uint16_t payload_len, - uint32_t ip_orig, uint16_t offset); -void DetectFtpbounceRegisterTests(void); -void DetectFtpbounceFree(void *); +static void DetectFtpbounceRegisterTests(void); +static int g_ftp_request_list_id = 0; + +static int InspectFtpRequest(ThreadVars *tv, + DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, + const Signature *s, const SigMatchData *smd, + Flow *f, uint8_t flags, void *alstate, + void *txv, uint64_t tx_id); /** * \brief Registration function for ftpbounce: keyword @@ -63,12 +69,24 @@ void DetectFtpbounceRegister(void) { sigmatch_table[DETECT_FTPBOUNCE].name = "ftpbounce"; sigmatch_table[DETECT_FTPBOUNCE].Setup = DetectFtpbounceSetup; - sigmatch_table[DETECT_FTPBOUNCE].Match = NULL; - sigmatch_table[DETECT_FTPBOUNCE].AppLayerMatch = DetectFtpbounceALMatch; - sigmatch_table[DETECT_FTPBOUNCE].Free = NULL; + sigmatch_table[DETECT_FTPBOUNCE].AppLayerTxMatch = DetectFtpbounceALMatch; sigmatch_table[DETECT_FTPBOUNCE].RegisterTests = DetectFtpbounceRegisterTests; sigmatch_table[DETECT_FTPBOUNCE].flags = SIGMATCH_NOOPT; - return; + + g_ftp_request_list_id = DetectBufferTypeRegister("ftp_request"); + + DetectAppLayerInspectEngineRegister("ftp_request", + ALPROTO_FTP, SIG_FLAG_TOSERVER, InspectFtpRequest); +} + +static int InspectFtpRequest(ThreadVars *tv, + DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, + const Signature *s, const SigMatchData *smd, + Flow *f, uint8_t flags, void *alstate, + void *txv, uint64_t tx_id) +{ + return DetectEngineInspectGenericList(tv, de_ctx, det_ctx, s, smd, + f, flags, alstate, txv, tx_id); } /** @@ -167,18 +185,19 @@ static int DetectFtpbounceMatchArgs(uint8_t *payload, uint16_t payload_len, * \retval 1 match */ static int DetectFtpbounceALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, - Flow *f, uint8_t flags, void *state, const Signature *s, - const SigMatchData *m) + Flow *f, uint8_t flags, + void *state, void *txv, + const Signature *s, const SigMatchCtx *m) { SCEnter(); - FtpState *ftp_state =(FtpState *)state; + + FtpState *ftp_state = (FtpState *)state; if (ftp_state == NULL) { SCLogDebug("no ftp state, no match"); SCReturnInt(0); } int ret = 0; - if (ftp_state->command == FTP_COMMAND_PORT) { ret = DetectFtpbounceMatchArgs(ftp_state->port_line, ftp_state->port_line_len, f->src.address.address_un_data32[0], @@ -206,9 +225,14 @@ int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbounces SigMatch *sm = NULL; + if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) { + SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); + return -1; + } + sm = SigMatchAlloc(); if (sm == NULL) { - goto error;; + return -1; } sm->type = DETECT_FTPBOUNCE; @@ -224,22 +248,11 @@ int DetectFtpbounceSetup(DetectEngineCtx *de_ctx, Signature *s, char *ftpbounces */ sm->ctx = NULL; - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_FTP) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_AMATCH); + SigMatchAppendSMToList(s, sm, g_ftp_request_list_id); s->alproto = ALPROTO_FTP; s->flags |= SIG_FLAG_APPLAYER; SCReturnInt(0); - -error: - if (sm != NULL) { - SigMatchFree(sm); - } - SCReturnInt(-1); } #ifdef UNITTESTS @@ -247,20 +260,19 @@ error: /** * \test DetectFtpbounceTestSetup01 is a test for the Setup ftpbounce */ -int DetectFtpbounceTestSetup01(void) +static int DetectFtpbounceTestSetup01(void) { - int res = 0; DetectEngineCtx *de_ctx = NULL; Signature *s = SigAlloc(); - if (s == NULL) - return 0; + FAIL_IF (s == NULL); /* ftpbounce doesn't accept options so the str is NULL */ - res = !DetectFtpbounceSetup(de_ctx, s, NULL); - res &= s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL && s->sm_lists[DETECT_SM_LIST_AMATCH]->type & DETECT_FTPBOUNCE; + FAIL_IF_NOT(DetectFtpbounceSetup(de_ctx, s, NULL) == 0); + FAIL_IF(s->sm_lists[g_ftp_request_list_id] == NULL); + FAIL_IF_NOT(s->sm_lists[g_ftp_request_list_id]->type & DETECT_FTPBOUNCE); SigFree(s); - return res; + PASS; } #include "stream-tcp-reassemble.h"