]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
eve/ftp: Bug fix and banner capture
authorZach Kelly <zach.kelly@lmco.com>
Thu, 23 May 2019 19:07:28 +0000 (15:07 -0400)
committerVictor Julien <victor@inliniac.net>
Wed, 17 Jul 2019 06:21:54 +0000 (08:21 +0200)
1. Correct off-by-one error in server response whitespace removal
2. Include banner response (before first command entered)

src/app-layer-ftp.c
src/output-json-ftp.c

index f1bc87e0779871b53df8dee105b6bbb8062060ca..fbcca8b5cf8046bfd08a08c3b1e20b397efbc930 100644 (file)
@@ -473,17 +473,21 @@ static void FtpTransferCmdFree(void *data)
 static uint32_t CopyCommandLine(uint8_t **dest, uint8_t *src, uint32_t length)
 {
     if (likely(length)) {
-        uint8_t *where = FTPCalloc(length, sizeof(char));
+        if (unlikely(length == UINT32_MAX)) {
+            return 0;
+        }
+        uint8_t *where = FTPCalloc(length + 1, sizeof(char));
         if (unlikely(where == NULL)) {
             return 0;
         }
         memcpy(where, src, length);
 
         /* Remove trailing newlines/carriage returns */
-        if (isspace((unsigned char)where[length - 1])) {
-            while(length && isspace((unsigned char)where[--length - 1]));
-            where[length] = '\0';
+        while (length && isspace((unsigned char) where[length - 1])) {
+            length--;
         }
+
+        where[length] = '\0';
         *dest = where;
     }
     /* either 0 or actual */
@@ -750,6 +754,7 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat
                             void *local_data, const uint8_t flags)
 {
     FtpState *state = (FtpState *)ftp_state;
+    FTPTransaction *tx = NULL;
     int retcode = 1;
     FTPTransaction *tx;
 
@@ -769,9 +774,9 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat
         tx->command_descriptor = &FtpCommands[FTP_COMMAND_MAX -1];
     } else {
         tx = FTPGetOldestTx(state);
+        state->curr_tx = tx;
     }
 
-    state->curr_tx = tx;
     if (state->command == FTP_COMMAND_AUTH_TLS) {
         if (input_len >= 4 && SCMemcmp("234 ", input, 4) == 0) {
             AppLayerRequestProtocolTLSUpgrade(f);
index 06807769c84128c468b91172466e8c1d84738c19..10a9b35e021b6842ce1d1e754af247c79eb80b23 100644 (file)
@@ -69,14 +69,21 @@ static void JsonFTPLogJSON(json_t *tjs, Flow *f, FTPTransaction *tx)
     } else {
         cjs = json_object();
         if (cjs) {
-            json_object_set_new(cjs, "command",
-                                json_string(tx->command_descriptor->command_name_upper));
+            FTPString *response;
+            if (tx->command_descriptor->command == FTP_COMMAND_UNKNOWN) {
+                // alternatively, `command` could be left out of the object completely
+                json_object_set_new(cjs, "command", json_null());
+            } else {
+                json_object_set_new(cjs, "command", json_string(tx->command_descriptor->command_name_upper));
+            }
             uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */
-            json_object_set_new(cjs, "command_data",
-                                tx->request_length >= min_length ?
+            if (tx->request_length > min_length) {
+                json_object_set_new(cjs, "command_data",
                                     JsonAddStringN((const char *)tx->request + min_length,
-                                                   tx->request_length - min_length) :
-                                    json_string(NULL));
+                                                   tx->request_length - min_length));
+            } else {
+                json_object_set_new(cjs, "command_data", json_string(NULL));
+            }
             if (!TAILQ_EMPTY(&tx->response_list)) {
                 json_t *js_resplist = json_array();
                 if (likely(js_resplist != NULL)) {