]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3690: telnet: added paf based splitter for telnet
authorBhargava Jandhyala (bjandhya) <bjandhya@cisco.com>
Tue, 7 Mar 2023 16:58:31 +0000 (16:58 +0000)
committerBhargava Jandhyala (bjandhya) <bjandhya@cisco.com>
Tue, 7 Mar 2023 16:58:31 +0000 (16:58 +0000)
Merge in SNORT/snort3 from ~SMANGHAT/snort3:snort_telnet_splitter to master

Squashed commit of the following:

commit 573f28712abe09bbcdd7d693986fffffa7eb6881
Author: Shailendra Manghate <smanghat@cisco.com>
Date:   Tue Mar 7 15:38:22 2023 +0530

    ftp_telnet: updated flushing around subnegotiation parameters

    The splitter will flush after EOL or SE. It will ignore EOL between SB and SE.

src/service_inspectors/ftp_telnet/CMakeLists.txt
src/service_inspectors/ftp_telnet/ftp.cc
src/service_inspectors/ftp_telnet/ftp_splitter.cc [deleted file]
src/service_inspectors/ftp_telnet/telnet.cc
src/service_inspectors/ftp_telnet/telnet_splitter.cc [new file with mode: 0644]
src/service_inspectors/ftp_telnet/telnet_splitter.h [moved from src/service_inspectors/ftp_telnet/ftp_splitter.h with 80% similarity]

index 760a5407898f9fec72d007d9debe95625cba2f13..c0ee5e28f882fcae58371bd1c03ce3dd7defec0c 100644 (file)
@@ -17,8 +17,8 @@ set (FILE_LIST
     ftp_print.cc
     ftp_print.h
     ftp_server.h
-    ftp_splitter.h
-    ftp_splitter.cc
+    telnet_splitter.h
+    telnet_splitter.cc
     ftpdata_splitter.h
     ftpdata_splitter.cc
     ftpp_return_codes.h
index 9f65dbe1ca2b592fcc86bf56d2113b707ec313af..f06405524b207b186885719bee701e31ff16a564 100644 (file)
@@ -35,7 +35,7 @@
 #include "ftp_module.h"
 #include "ftp_parse.h"
 #include "ftp_print.h"
-#include "ftp_splitter.h"
+#include "telnet_splitter.h"
 #include "ftpp_return_codes.h"
 #include "ftpp_si.h"
 #include "pp_ftp.h"
@@ -250,7 +250,7 @@ void FtpServer::show(const SnortConfig*) const
 
 StreamSplitter* FtpServer::get_splitter(bool c2s)
 {
-    return new FtpSplitter(c2s);
+    return new TelnetSplitter(c2s);
 }
 
 void FtpServer::eval(Packet* p)
diff --git a/src/service_inspectors/ftp_telnet/ftp_splitter.cc b/src/service_inspectors/ftp_telnet/ftp_splitter.cc
deleted file mode 100644 (file)
index 96059dd..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2023 Cisco and/or its affiliates. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation.  You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//--------------------------------------------------------------------------
-// ftp_splitter.cc author Russ Combs <rucombs@cisco.com>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "ftp_splitter.h"
-#include "protocols/ssl.h"
-#include "protocols/packet.h"
-#include "utils/util.h"
-
-#include <cstring>
-
-using namespace snort;
-
-FtpSplitter::FtpSplitter(bool c2s) : StreamSplitter(c2s) { }
-
-// flush at last CR or LF in data
-// preproc will deal with any pipelined commands
-StreamSplitter::Status FtpSplitter::scan(
-    Packet* p, const uint8_t* data, uint32_t len,
-    uint32_t, uint32_t* fp)
-{
-    if ( IsSSL(data, len, p->packet_flags) )
-    {
-        *fp = len;
-        return FLUSH;
-    }
-
-    const uint8_t* cr = snort_memrchr(data, '\r', len);
-    const uint8_t* lf = snort_memrchr(data, '\n', len);
-
-    const uint8_t* ptr = nullptr;
-
-    if ( cr && !lf )
-        ptr = cr;
-    else if ( !cr && lf )
-        ptr = lf;
-    else if ( cr && lf )
-        ptr = ( cr > lf ) ? cr : lf;
-
-    if ( !ptr )
-        return SEARCH;
-
-    *fp = ptr - data + 1;
-    return FLUSH;
-}
-
index 4b2ebf7bf9fdf3aaa2baa43031f7b6b081ecd8fd..fad8806fa23ba2179c5dd62673d3e3b7ba470642 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "ft_main.h"
 #include "ftp_print.h"
-#include "ftp_splitter.h"
+#include "telnet_splitter.h"
 #include "ftpp_return_codes.h"
 #include "ftpp_si.h"
 #include "ftpp_ui_config.h"
@@ -192,7 +192,7 @@ public:
     void clear(Packet*) override;
 
     StreamSplitter* get_splitter(bool c2s) override
-    { return new FtpSplitter(c2s); }
+    { return new TelnetSplitter(c2s); }
 
 private:
     TELNET_PROTO_CONF* config;
diff --git a/src/service_inspectors/ftp_telnet/telnet_splitter.cc b/src/service_inspectors/ftp_telnet/telnet_splitter.cc
new file mode 100644 (file)
index 0000000..0ba0a6d
--- /dev/null
@@ -0,0 +1,126 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2023 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// ftp_splitter.cc author Shailendra Manghate <smanghat@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "telnet_splitter.h"
+
+#include <cstring>
+
+#include "protocols/ssl.h"
+#include "protocols/packet.h"
+#include "utils/util.h"
+
+
+using namespace snort;
+
+TelnetSplitter::TelnetSplitter(bool c2s) : StreamSplitter(c2s) { }
+
+// flush at last CR or LF in data
+// preproc will deal with any pipelined commands
+StreamSplitter::Status TelnetSplitter::scan(
+    Packet* p, const uint8_t* data, uint32_t len,
+    uint32_t, uint32_t* fp)
+{
+    if ( IsSSL(data, len, p->packet_flags) )
+    {
+        *fp = len;
+        return FLUSH;
+    }
+
+    const uint8_t* read_ptr = data;
+    const uint8_t* end = data + len;
+    const uint8_t* fp_ptr = nullptr;
+
+    while ( read_ptr < end )
+    {
+        switch ( state )
+        {
+            case TELNET_NONE:
+            {
+                const uint8_t* cr = static_cast<const uint8_t*>(memchr(read_ptr, '\r', end - read_ptr));
+                const uint8_t* lf = static_cast<const uint8_t*>(memchr(read_ptr, '\n', end - read_ptr));
+                const uint8_t* ptr = nullptr;
+                if ( cr && !lf )
+                    ptr = cr;
+                else if ( !cr && lf )
+                    ptr = lf;
+                else if ( cr && lf )
+                    ptr = ( cr > lf ) ? cr : lf;
+                if ( ptr )
+                {
+                    fp_ptr = ptr;
+                    read_ptr = fp_ptr;
+                }
+
+                const uint8_t* iac_ptr = static_cast<const uint8_t*>(memchr( read_ptr, TNC_IAC, end - read_ptr));
+                if ( iac_ptr )
+                {
+                    state = TELNET_IAC;
+                    read_ptr = iac_ptr;
+                }
+                break;
+            }
+            case TELNET_IAC:
+            {
+                if ( *read_ptr == (unsigned char)TNC_SB )
+                    state = TELNET_IAC_SB;
+                else if ( *read_ptr != (unsigned char)TNC_IAC )
+                    state = TELNET_NONE;
+                break;
+            }
+            case TELNET_IAC_SB:
+            {
+                const uint8_t* iac_se_ptr = static_cast<const uint8_t*>(memchr(read_ptr, TNC_IAC, end - read_ptr));
+                if ( iac_se_ptr )
+                {
+                    state = TELNET_IAC_SB_IAC;
+                    read_ptr = iac_se_ptr;
+                }
+                else
+                    read_ptr = end;
+                break;
+            }
+            case TELNET_IAC_SB_IAC:
+            {
+                if ( *read_ptr == (unsigned char)TNC_SE )
+                {
+                    fp_ptr = read_ptr;
+                    state = TELNET_NONE;
+                }
+                else
+                    state = TELNET_IAC_SB;
+                break;
+            }
+        }
+
+        if ( read_ptr < end )
+            read_ptr++;
+    }
+
+    if ( fp_ptr )
+    {
+        *fp = fp_ptr - data + 1;
+        return FLUSH;
+    }
+    return SEARCH;
+}
+
similarity index 80%
rename from src/service_inspectors/ftp_telnet/ftp_splitter.h
rename to src/service_inspectors/ftp_telnet/telnet_splitter.h
index de6d192175dc806f5e46bbf8d6e6d4c916109059..aa9c9f65b3f4bcddf3aab11f5c66e066ec6c7cf7 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-#ifndef FTP_SPLITTER_H
-#define FTP_SPLITTER_H
+#ifndef TELNET_SPLITTER_H
+#define TELNET_SPLITTER_H
 
 #include "stream/stream_splitter.h"
+#include "pp_telnet.h"
 
-class FtpSplitter : public snort::StreamSplitter
+class TelnetSplitter : public snort::StreamSplitter
 {
 public:
-    FtpSplitter(bool c2s);
+    TelnetSplitter(bool c2s);
 
     Status scan(snort::Packet*, const uint8_t* data, uint32_t len,
         uint32_t flags, uint32_t* fp) override;
 
     bool is_paf() override { return true; }
+private:
+    enum TelnetState { TELNET_NONE, TELNET_IAC, TELNET_IAC_SB, TELNET_IAC_SB_IAC };
+    TelnetState state { TELNET_NONE };
 };
 
 #endif