]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ftp: parser and ftpbounce update
authorVictor Julien <victor@inliniac.net>
Thu, 22 Dec 2016 14:21:32 +0000 (15:21 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 16 Feb 2017 09:35:42 +0000 (10:35 +0100)
Convert parser to TX API.

Convert ftpbounce keyword to use that.

src/app-layer-ftp.c
src/app-layer-ftp.h
src/detect-ftpbounce.c

index 974ec2e561bb33f8b41da2c40377ab7e29171f65..7bdd404369349b8ebf96a998a05cffcb46a93e8f 100644 (file)
@@ -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);
index 4a001290d554487c22675db2e87939c8b0c1887e..de93f5f7739818c88e21ef5269d9f08e603aac14 100644 (file)
 #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);
index 7895c854fb86a26fd49c2ca7bc87f3f20f9e76ba..0e2c2a07b583d0cfc6b98bc7ee9871dbc9baea63 100644 (file)
 #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"