ftp: parser and ftpbounce update

Convert parser to TX API.

Convert ftpbounce keyword to use that.
pull/2559/head
Victor Julien 8 years ago
parent d9a300cd8c
commit 402eb645a0

@ -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);

@ -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);

@ -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"

Loading…
Cancel
Save