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);
#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,
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);
#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
{
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);
}
/**
* \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],
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;
*/
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
/**
* \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"