]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
eve/ftp: Log initial responses
authorJeff Lucovsky <jeff@lucovsky.org>
Sat, 25 May 2019 14:08:31 +0000 (07:08 -0700)
committerVictor Julien <victor@inliniac.net>
Wed, 17 Jul 2019 06:21:54 +0000 (08:21 +0200)
This changeset ensures that unknown commands are logged.
Unknown commands are either
- Banner responses when connecting to the FTP port
- Commands not includes in the FtpCommands descriptor table

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

index 176a804243122229ed7d799f07a7d80323f01ac1..f1bc87e0779871b53df8dee105b6bbb8062060ca 100644 (file)
@@ -481,7 +481,7 @@ static uint32_t CopyCommandLine(uint8_t **dest, uint8_t *src, uint32_t length)
 
         /* Remove trailing newlines/carriage returns */
         if (isspace((unsigned char)where[length - 1])) {
-            while(length && isspace((unsigned char)where[--length]));
+            while(length && isspace((unsigned char)where[--length - 1]));
             where[length] = '\0';
         }
         *dest = where;
@@ -751,12 +751,26 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat
 {
     FtpState *state = (FtpState *)ftp_state;
     int retcode = 1;
+    FTPTransaction *tx;
 
     if (state->command == FTP_COMMAND_UNKNOWN) {
-        return 1;
+        if (unlikely(input_len == 0)) {
+            return 1;
+        }
+
+        tx = FTPGetOldestTx(state);
+        if (tx == NULL) {
+            tx = FTPTransactionCreate(state);
+        }
+        if (unlikely(tx == NULL)) {
+            return -1;
+        }
+        /* unknown */
+        tx->command_descriptor = &FtpCommands[FTP_COMMAND_MAX -1];
+    } else {
+        tx = FTPGetOldestTx(state);
     }
 
-    FTPTransaction *tx = FTPGetOldestTx(state);
     state->curr_tx = tx;
     if (state->command == FTP_COMMAND_AUTH_TLS) {
         if (input_len >= 4 && SCMemcmp("234 ", input, 4) == 0) {
index 755692084fffe53c4df9132a5b687dfd38ddf864..06807769c84128c468b91172466e8c1d84738c19 100644 (file)
@@ -66,20 +66,21 @@ static void JsonFTPLogJSON(json_t *tjs, Flow *f, FTPTransaction *tx)
     json_t *cjs = NULL;
     if (f->alproto == ALPROTO_FTPDATA) {
         cjs = JsonFTPDataAddMetadata(f);
-    } else if (tx->command_descriptor->command != FTP_COMMAND_UNKNOWN) {
+    } else {
         cjs = json_object();
         if (cjs) {
-            FTPString *response;
-            json_object_set_new(cjs, "command", json_string(tx->command_descriptor->command_name_upper));
+            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 */
-            if (tx->request_length >= min_length) {
-                json_object_set_new(cjs, "command_data",
+            json_object_set_new(cjs, "command_data",
+                                tx->request_length >= min_length ?
                                     JsonAddStringN((const char *)tx->request + min_length,
-                                                   tx->request_length - min_length));
-            }
+                                                   tx->request_length - min_length) :
+                                    json_string(NULL));
             if (!TAILQ_EMPTY(&tx->response_list)) {
                 json_t *js_resplist = json_array();
                 if (likely(js_resplist != NULL)) {
+                    FTPString *response;
                     json_t *resp_code = NULL;
                     TAILQ_FOREACH(response, &tx->response_list, next) {
                         if (!resp_code && response->len >= 3)  {