]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #609 in SNORT/snort3 from smbv2 to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 7 Sep 2016 17:02:57 +0000 (13:02 -0400)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 7 Sep 2016 17:02:57 +0000 (13:02 -0400)
Squashed commit of the following:

commit a35102052f7c311bf47ac68f74fad952c3f79121
Author: mdagon <mdagon@cisco.com>
Date:   Tue Aug 30 14:37:28 2016 -0400

    Smbv2

14 files changed:
src/protocols/packet.h
src/service_inspectors/dce_rpc/CMakeLists.txt
src/service_inspectors/dce_rpc/Makefile.am
src/service_inspectors/dce_rpc/dce_common.h
src/service_inspectors/dce_rpc/dce_smb.cc
src/service_inspectors/dce_rpc/dce_smb.h
src/service_inspectors/dce_rpc/dce_smb2.cc [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_smb2.h [new file with mode: 0644]
src/service_inspectors/dce_rpc/dce_smb_module.cc
src/service_inspectors/dce_rpc/dce_smb_module.h
src/service_inspectors/dce_rpc/dce_smb_utils.cc
src/service_inspectors/dce_rpc/dce_smb_utils.h
tools/snort2lua/preprocessor_states/pps_dcerpc.cc
tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc

index 4fc678bbb330bf401932367d4435b00a63f87337..ef51234467e02a582df006c09f8f1c2ecec4c583 100644 (file)
@@ -255,19 +255,19 @@ struct SO_PUBLIC Packet
     bool is_from_server() const
     { return (packet_flags & PKT_FROM_SERVER) != 0; }
 
-    bool is_portscan()
+    bool is_portscan() const
     { return is_cooked() and (pseudo_type == PSEUDO_PKT_PS); }
 
-    bool is_full_pdu()
+    bool is_full_pdu() const
     { return (packet_flags & PKT_PDU_FULL) == PKT_PDU_FULL; }
 
-    bool is_pdu_start()
+    bool is_pdu_start() const
     { return (packet_flags & PKT_PDU_HEAD) != 0; }
 
-    bool has_paf_payload()
+    bool has_paf_payload() const
     { return (packet_flags & PKT_REBUILT_STREAM) or is_full_pdu(); }
 
-    bool is_rebuilt()
+    bool is_rebuilt() const
     { return (packet_flags & (PKT_REBUILT_STREAM|PKT_REBUILT_FRAG)) != 0; }
 
     int16_t get_application_protocol()
index 98c0e2d2d345e736165e4edc4c8b75a83cbc5039..8b9afe9f04dd64307fa28587c61f2f89d519dc26 100644 (file)
@@ -8,6 +8,8 @@ set( FILE_LIST
    dce_list.cc
    dce_smb.cc 
    dce_smb.h
+   dce_smb2.cc
+   dce_smb2.h
    dce_smb_commands.cc
    dce_smb_commands.h 
    dce_smb_module.cc 
index 240555a4b4ce82b0b8bdf32aaf59ee57deda99bb..867d0301b13bf267482da7191c667367fa30351a 100644 (file)
@@ -7,6 +7,8 @@ dce_list.cc \
 dce_list.h \
 dce_smb.cc \
 dce_smb.h \
+dce_smb2.cc \
+dce_smb2.h \
 dce_smb_commands.cc \
 dce_smb_commands.h \
 dce_smb_module.cc \
index 47d4e2356e24a803fe3f8034eb34c2c57b648640..0e6a56a85fad797fa85a840aadc85741f8143829 100644 (file)
@@ -185,6 +185,7 @@ enum DCE2_SsnFlag
     DCE2_SSN_FLAG__NONE               = 0x0000,
     DCE2_SSN_FLAG__AUTODETECTED       = 0x0001,
     DCE2_SSN_FLAG__NO_INSPECT         = 0x0002,
+    DCE2_SSN_FLAG__SMB2               = 0x0004,
     DCE2_SSN_FLAG__ALL                = 0xffff
 };
 
index 7afb188773fbe578c7b72f3cab5845a3afa2bd02..a93fdb67fedd7ffff7d42665d522654c3fd1f47f 100644 (file)
@@ -19,6 +19,7 @@
 // dce_smb.cc author Rashmi Pitre <rrp@cisco.com>
 
 #include "dce_smb.h"
+#include "dce_smb2.h"
 #include "dce_smb_utils.h"
 #include "dce_smb_paf.h"
 #include "dce_smb_module.h"
@@ -1493,7 +1494,7 @@ static void DCE2_SmbProcessRawData(DCE2_SmbSsnData* ssd, const uint8_t* nb_ptr,
     if (DCE2_SsnFromClient(ssd->sd.wire_pkt))
     {
         DebugMessage(DEBUG_DCE_SMB, "Raw data: Write Raw\n");
-        DebugFormat(DEBUG_DCE_SMB, "Request Fid: 0x%04X\n", ftracker->fid);
+        DebugFormat(DEBUG_DCE_SMB, "Request Fid: 0x%04X\n", ftracker->fid_v1);
 
         if (nb_len > ssd->cur_rtracker->writeraw_remaining)
         {
@@ -1519,7 +1520,7 @@ static void DCE2_SmbProcessRawData(DCE2_SmbSsnData* ssd, const uint8_t* nb_ptr,
     else
     {
         DebugMessage(DEBUG_DCE_SMB, "Raw data: Read Raw\n");
-        DebugFormat(DEBUG_DCE_SMB, "Response Fid: 0x%04X\n", ftracker->fid);
+        DebugFormat(DEBUG_DCE_SMB, "Response Fid: 0x%04X\n", ftracker->fid_v1);
 
         remove_rtracker = true;
     }
@@ -1638,6 +1639,12 @@ static void DCE2_SmbDataFree(DCE2_SmbSsnData* ssd)
         DCE2_BufferDestroy(ssd->srv_seg);
         ssd->srv_seg = nullptr;
     }
+
+    if (ssd->smb2_requests != nullptr)
+    {
+        DCE2_Smb2CleanRequests(ssd->smb2_requests);
+        ssd->smb2_requests = nullptr;
+    }
 }
 
 Dce2SmbFlowData::Dce2SmbFlowData() : FlowData(flow_id)
@@ -1691,7 +1698,7 @@ static DCE2_SmbSsnData* dce2_create_new_smb_session(Packet* p, dce2SmbProtoConf*
             dce2_smb_sess->pdu_state = DCE2_SMB_PDU_STATE__COMMAND;
             dce2_smb_sess->uid = DCE2_SENTINEL;
             dce2_smb_sess->tid = DCE2_SENTINEL;
-            dce2_smb_sess->ftracker.fid = DCE2_SENTINEL;
+            dce2_smb_sess->ftracker.fid_v1 = DCE2_SENTINEL;
             dce2_smb_sess->rtracker.mid = DCE2_SENTINEL;
             dce2_smb_sess->max_file_depth = FileService::get_max_file_depth();
 
@@ -1854,19 +1861,9 @@ static DCE2_Ret DCE2_NbssHdrChecks(DCE2_SmbSsnData* ssd, const NbssHdr* nb_hdr)
     return DCE2_RET__IGNORE;
 }
 
-/********************************************************************
- * Function: DCE2_SmbProcess()
- *
- * Purpose:
- *  This is the main entry point for SMB processing.
- *
- * Arguments:
- *  DCE2_SmbSsnData * - the session data structure.
- *
- * Returns: None
- *
- ********************************************************************/
-static void DCE2_SmbProcess(DCE2_SmbSsnData* ssd)
+
+// This is the main entry point for SMB1 processing.
+static void DCE2_Smb1Process(DCE2_SmbSsnData* ssd)
 {
     DebugMessage(DEBUG_DCE_SMB, "Processing SMB packet.\n");
     dce2_smb_stats.smb_pkts++;
@@ -2043,10 +2040,14 @@ static void DCE2_SmbProcess(DCE2_SmbSsnData* ssd)
                 smb_hdr = (SmbNtHdr*)(DCE2_BufferData(*seg_buf) + sizeof(NbssHdr));
             }
 
-            // FIXIT-L Don't support SMB2 yet
             if (SmbId(smb_hdr) == DCE2_SMB2_ID)
             {
-                ssd->sd.flags |= DCE2_SSN_FLAG__NO_INSPECT;
+                ssd->sd.flags |= DCE2_SSN_FLAG__SMB2;
+                if (!DCE2_GcIsLegacyMode((dce2SmbProtoConf*)ssd->sd.config))
+                {
+                    DCE2_Smb2InitFileTracker(&(ssd->ftracker), false, 0);
+                    DCE2_Smb2Process(ssd);
+                }
                 return;
             }
 
@@ -2233,6 +2234,44 @@ static void DCE2_SmbProcess(DCE2_SmbSsnData* ssd)
     }
 }
 
+// This is the main entry point for SMB processing
+void DCE2_SmbProcess(DCE2_SmbSsnData* ssd)
+{
+    if (DCE2_GcIsLegacyMode((dce2SmbProtoConf*)ssd->sd.config))
+    {
+        DCE2_Smb1Process(ssd);
+        return;
+    }
+
+    Packet* p = ssd->sd.wire_pkt;
+    DCE2_SmbVersion smb_version = DCE2_Smb2Version(p);
+    if (smb_version == DCE2_SMB_VERISON_1)
+    {
+        if ((ssd->sd.flags & DCE2_SSN_FLAG__SMB2))
+        {
+            DebugMessage(DEBUG_DCE_SMB, "SMB1 packet detected!\n");
+            ssd->sd.flags &= ~DCE2_SSN_FLAG__SMB2;
+            DCE2_SmbCleanFileTracker(&(ssd->ftracker));
+            ssd->ftracker.is_smb2 = false;
+        }
+    }
+    else if (smb_version == DCE2_SMB_VERISON_2)
+    {
+        if (!(ssd->sd.flags & DCE2_SSN_FLAG__SMB2))
+        {
+            DebugMessage(DEBUG_DCE_SMB, "SMB2 packet detected!\n");
+            DCE2_SmbCleanFileTracker(&(ssd->ftracker));
+            DCE2_Smb2InitFileTracker(&(ssd->ftracker), 0, 0);
+            ssd->sd.flags |= DCE2_SSN_FLAG__SMB2;
+        }
+    }
+
+    if (ssd->sd.flags & DCE2_SSN_FLAG__SMB2)
+        DCE2_Smb2Process(ssd);
+    else
+        DCE2_Smb1Process(ssd);
+}
+
 /********************************************************************
  * Function: DCE2_SmbInitGlobals()
  *
index 8a7df54ef12e5a234bedbe2c83d921edfcad4e41..6c22ab3b02e5b5b20188c53c969e42991da76cb7 100644 (file)
@@ -73,6 +73,8 @@
 #define DCE2_SMB_INVALID_SETUP_COUNT 55
 #define DCE2_SMB_MULTIPLE_NEGOTIATIONS 56
 #define DCE2_SMB_EVASIVE_FILE_ATTRS 57
+#define DCE2_SMB_INVALID_FILE_OFFSET 58
+#define DCE2_SMB_BAD_NEXT_COMMAND_OFFSET 59
 
 #define DCE2_SMB_BAD_NBSS_TYPE_STR "SMB - Bad NetBIOS Session Service session type."
 #define DCE2_SMB_BAD_TYPE_STR  "SMB - Bad SMB message type."
     "SMB - Client attempted multiple dialect negotiations on session."
 #define DCE2_SMB_EVASIVE_FILE_ATTRS_STR \
     "SMB - Client attempted to create or set a file's attributes to readonly/hidden/system."
+#define DCE2_SMB_INVALID_FILE_OFFSET_STR \
+    "SMB - File offset provided is greater than file size specified"
+#define DCE2_SMB_BAD_NEXT_COMMAND_OFFSET_STR \
+    "SMB - Next command specified in SMB2 header is beyond payload boundary"
 
 #define SMB_MAX_NUM_COMS   256
 
@@ -217,6 +223,14 @@ struct dce2SmbStats
     uint64_t smb_nt_transact_subcom_stats[2][NT_TRANSACT_SUBCOM_MAX+1];
     */
     PegCount smb_files_processed;
+    /* SMB2 stats */
+    PegCount smb2_create;
+    PegCount smb2_write;
+    PegCount smb2_read;
+    PegCount smb2_set_info;
+    PegCount smb2_tree_connect;
+    PegCount smb2_tree_disconnect;
+    PegCount smb2_close;
 };
 
 extern THREAD_LOCAL dce2SmbStats dce2_smb_stats;
@@ -582,11 +596,25 @@ struct DCE2_SmbFileChunk
 
 struct DCE2_SmbFileTracker
 {
-    int fid;   // A signed integer so it can be set to sentinel
-    uint16_t uid;
-    uint16_t tid;
+    union
+    {
+        struct
+        {
+            int file_id;   // A signed integer so it can be set to sentinel
+            uint16_t u_id;
+            uint16_t tree_id;
+        } id_smb1;
+
+        struct
+        {
+            uint64_t file_id;
+        } id_smb2;
+    } file_key;
+
     bool is_ipc;
+    bool is_smb2;
     char* file_name;
+    uint16_t file_name_size;
 
     union
     {
@@ -618,6 +646,10 @@ struct DCE2_SmbFileTracker
         } file;
     } tracker;
 
+#define fid_v1                file_key.id_smb1.file_id
+#define uid_v1                file_key.id_smb1.u_id
+#define tid_v1                file_key.id_smb1.tree_id
+#define fid_v2                file_key.id_smb2.file_id
 #define fp_byte_mode   tracker.nmpipe.byte_mode
 #define fp_used        tracker.nmpipe.used
 #define fp_writex_raw  tracker.nmpipe.writex_raw
@@ -631,6 +663,22 @@ struct DCE2_SmbFileTracker
 #define ff_sequential_only    tracker.file.sequential_only
 };
 
+enum DCE2_SmbVersion
+{
+    DCE2_SMB_VERISON_NULL,
+    DCE2_SMB_VERISON_1,
+    DCE2_SMB_VERISON_2
+};
+
+struct Smb2Request
+{
+    uint64_t message_id;   /* identifies a message uniquely on connection */
+    uint64_t offset;       /* data offset */
+    uint64_t file_id;      /* file id */
+    struct Smb2Request* next;
+    struct Smb2Request* previous;
+};
+
 struct DCE2_SmbTransactionTracker
 {
     int smb_type;
@@ -728,6 +776,8 @@ struct DCE2_SmbSsnData
     // This is a reference to a file tracker so shouldn't be freed.
     DCE2_SmbFileTracker* fapi_ftracker;
 
+    Smb2Request* smb2_requests;
+
 #ifdef ACTIVE_RESPONSE
     DCE2_SmbFileTracker* fb_ftracker;
     bool block_pdus;
diff --git a/src/service_inspectors/dce_rpc/dce_smb2.cc b/src/service_inspectors/dce_rpc/dce_smb2.cc
new file mode 100644 (file)
index 0000000..21f556f
--- /dev/null
@@ -0,0 +1,854 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-2016 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.
+//--------------------------------------------------------------------------
+
+// SMB2 file processing
+// Author(s):  Hui Cao <huica@cisco.com>
+
+#include "dce_smb2.h"
+#include "dce_list.h"
+#include "dce_smb_module.h"
+#include "dce_smb_utils.h"
+#include "detection/detection_util.h"
+#include "main/snort_debug.h"
+
+#define   UNKNOWN_FILE_SIZE                  ~0
+
+// FIXIT-L port fileCache related code along with
+// DCE2_Smb2Init, DCE2_Smb2Close and DCE2_Smb2UpdateStats
+
+static void DCE2_Smb2Inspect(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    const uint8_t* end);
+
+static char* DCE2_Smb2GetFileName(const uint8_t* data,
+    uint32_t data_len, bool unicode, bool file_name_only)
+{
+    char* str;
+    uint32_t path_end, name_start, str_len = unicode ? data_len - 1 : data_len;
+    const uint8_t inc = unicode ? 2 : 1;
+
+    if (data_len < inc)
+        return nullptr;
+
+    // Move forward.  Don't know if the end of data is actually
+    // the end of the string.
+    for (path_end = 0, name_start = 0; path_end < str_len; path_end += inc)
+    {
+        uint16_t uchar = unicode ? alignedNtohs((uint16_t*)(data + path_end)) : data[path_end];
+
+        if (uchar == 0)
+            break;
+        else if (file_name_only && ((uchar == 0x002F) || (uchar == 0x005C)))  // slash and
+                                                                              // back-slash
+            name_start = path_end + inc;
+    }
+
+    // Only got a NULL byte or nothing after slash/back-slash or too big.
+    if ((path_end == 0) || (name_start == path_end)
+        || (file_name_only && (path_end > DCE2_SMB_MAX_COMP_LEN))
+        || (path_end > DCE2_SMB_MAX_PATH_LEN))
+        return nullptr;
+
+    str = (char*)snort_calloc(((path_end-name_start)>>(inc-1))+1);
+
+    uint32_t ind;
+    for (ind = 0; name_start < path_end; name_start += inc, ind++)
+    {
+        if ((int)data[name_start])
+            str[ind] = (char)data[name_start];
+        else
+            str[ind] = '.';
+    }
+
+    str[ind] = 0;
+
+    return str;
+}
+
+static inline uint32_t Smb2Tid(const Smb2Hdr* hdr)
+{
+    return alignedNtohl(&(((Smb2SyncHdr*)hdr)->tree_id));
+}
+
+static int DCE2_Smb2TidCompare(const void* a, const void* b)
+{
+    uint32_t x = (uint32_t)(uintptr_t)a;
+    uint32_t y = (uint32_t)(uintptr_t)b;
+
+    if (x == y)
+        return 0;
+
+    /* Only care about equality for finding */
+    return -1;
+}
+
+static inline void DCE2_Smb2InsertTid(DCE2_SmbSsnData* ssd, const uint32_t tid,
+    const uint8_t share_type)
+{
+    bool is_ipc = (share_type != SMB2_SHARE_TYPE_DISK);
+
+    if (!is_ipc && (!DCE2_ScSmbFileInspection((dce2SmbProtoConf*)ssd->sd.config)
+        || ((ssd->max_file_depth == -1) && DCE2_ScSmbFileDepth(
+        (dce2SmbProtoConf*)ssd->sd.config) == -1)))
+    {
+        DebugFormat(DEBUG_DCE_SMB, "Not inserting TID (%u) "
+            "because it's not IPC and not inspecting normal file "
+            "data.", tid);
+        return;
+    }
+
+    if (is_ipc)
+    {
+        DebugFormat(DEBUG_DCE_SMB, "Not inserting TID (%u) "
+            "because it's IPC and only inspecting normal file data.", tid);
+        return;
+    }
+
+    DebugFormat(DEBUG_DCE_SMB, "Inserting Tid: %u\n", tid);
+
+    if (ssd->tids == nullptr)
+    {
+        ssd->tids = DCE2_ListNew(DCE2_LIST_TYPE__SPLAYED, DCE2_Smb2TidCompare,
+            nullptr, nullptr, DCE2_LIST_FLAG__NO_DUPS);
+
+        if (ssd->tids == nullptr)
+        {
+            return;
+        }
+    }
+
+    DCE2_ListInsert(ssd->tids, (void*)(uintptr_t)tid, (void*)(uintptr_t)share_type);
+}
+
+static DCE2_Ret DCE2_Smb2FindTid(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr)
+{
+    /* Still process async commands*/
+    if (alignedNtohl(&(smb_hdr->flags)) & SMB2_FLAGS_ASYNC_COMMAND)
+        return DCE2_RET__SUCCESS;
+
+    return DCE2_ListFindKey(ssd->tids, (void*)(uintptr_t)Smb2Tid(smb_hdr));
+}
+
+static inline void DCE2_Smb2RemoveTid(DCE2_SmbSsnData* ssd, const uint32_t tid)
+{
+    DCE2_ListRemove(ssd->tids, (void*)(uintptr_t)tid);
+}
+
+static inline void DCE2_Smb2StoreRequest(DCE2_SmbSsnData* ssd,
+    uint64_t message_id, uint64_t offset, uint64_t file_id)
+{
+    Smb2Request* request = ssd->smb2_requests;
+    ssd->max_outstanding_requests = 128; /* windows client max */
+
+    while (request)
+    {
+        if (request->message_id == message_id)
+            return;
+        request = request->next;
+    }
+
+    request = (Smb2Request*)snort_calloc(sizeof(*request));
+
+    ssd->outstanding_requests++;
+
+    if (ssd->outstanding_requests >= ssd->max_outstanding_requests)
+    {
+        dce_alert(GID_DCE2, DCE2_SMB_MAX_REQS_EXCEEDED, (dce2CommonStats*)&dce2_smb_stats);
+        snort_free((void*)request);
+        return;
+    }
+
+    request->message_id = message_id;
+    request->offset = offset;
+    request->file_id = file_id;
+
+    request->next = ssd->smb2_requests;
+    request->previous = nullptr;
+    if (ssd->smb2_requests)
+        ssd->smb2_requests->previous = request;
+    ssd->smb2_requests = request;
+}
+
+static inline Smb2Request* DCE2_Smb2GetRequest(DCE2_SmbSsnData* ssd,
+    uint64_t message_id)
+{
+    Smb2Request* request = ssd->smb2_requests;
+    while (request)
+    {
+        if (request->message_id == message_id)
+            return request;
+        request = request->next;
+    }
+
+    return nullptr;
+}
+
+static inline void DCE2_Smb2RemoveRequest(DCE2_SmbSsnData* ssd,
+    Smb2Request* request)
+{
+    if (request->previous)
+    {
+        request->previous->next = request->next;
+    }
+
+    if (request->next)
+    {
+        request->next->previous = request->previous;
+    }
+
+    if (request == ssd->smb2_requests)
+    {
+        ssd->smb2_requests =  request->next;
+    }
+
+    ssd->outstanding_requests--;
+    snort_free((void*)request);
+}
+
+static inline void DCE2_Smb2FreeFileName(DCE2_SmbFileTracker* ftracker)
+{
+    if (ftracker->file_name)
+    {
+        snort_free((void*)ftracker->file_name);
+        ftracker->file_name = nullptr;
+    }
+    ftracker->file_name_size = 0;
+}
+
+static inline void DCE2_Smb2ResetFileName(DCE2_SmbFileTracker* ftracker)
+{
+    // FIXIT-L remove snort_free once file cache is ported.
+    if (ftracker->file_name)
+    {
+        snort_free((void*)ftracker->file_name);
+    }
+    ftracker->file_name = nullptr;
+    ftracker->file_name_size = 0;
+}
+
+static inline void DCE2_Smb2ProcessFileData(DCE2_SmbSsnData* ssd, const uint8_t* file_data,
+    uint32_t data_size, bool)
+{
+    int64_t file_detection_depth = DCE2_ScSmbFileDepth((dce2SmbProtoConf*)ssd->sd.config);
+    int64_t detection_size = 0;
+
+    if (file_detection_depth == 0)
+        detection_size = data_size;
+    else if ( ssd->ftracker.tracker.file.file_offset < (uint64_t)file_detection_depth)
+    {
+        if ( file_detection_depth - ssd->ftracker.tracker.file.file_offset < data_size )
+            detection_size = file_detection_depth - ssd->ftracker.tracker.file.file_offset;
+        else
+            detection_size = data_size;
+    }
+
+    if (detection_size)
+    {
+        set_file_data((uint8_t*)file_data,
+            (detection_size > UINT16_MAX) ? UINT16_MAX : (uint16_t)detection_size);
+
+        DCE2_FileDetect();
+    }
+
+// FIXIT-L port file processing
+/*
+    _dpd.fileAPI->file_segment_process(fileCache, (void *)ssd->sd.wire_pkt,
+            ssd->ftracker.fid_v2, ssd->ftracker.tracker.file.file_size,
+            file_data, data_size, ssd->ftracker.tracker.file.file_offset,
+            upload);
+*/
+}
+
+/********************************************************************
+ *
+ * Process tree connect command
+ * Share type is defined here
+ *
+ ********************************************************************/
+static void DCE2_Smb2TreeConnect(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    /* Using structure size to decide whether it is response or request*/
+    uint16_t structure_size;
+    Smb2TreeConnectResponseHdr* smb_tree_connect_hdr = (Smb2TreeConnectResponseHdr*)smb_data;
+
+    if ((const uint8_t*)smb_tree_connect_hdr + SMB2_TREE_CONNECT_RESPONSE_STRUC_SIZE > end)
+        return;
+
+    structure_size = alignedNtohs(&(smb_tree_connect_hdr->structure_size));
+
+    if (structure_size == SMB2_TREE_CONNECT_RESPONSE_STRUC_SIZE)
+    {
+        DCE2_Smb2InsertTid(ssd, Smb2Tid(smb_hdr), smb_tree_connect_hdr->share_type);
+    }
+}
+
+/********************************************************************
+ *
+ * Process tree connect command
+ * Share type is defined here
+ *
+ ********************************************************************/
+static void DCE2_Smb2TreeDisconnect(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    /* Using structure size to decide whether it is response or request*/
+    uint16_t structure_size;
+    Smb2TreeDisConnectHdr* smb_tree_disconnect_hdr = (Smb2TreeDisConnectHdr*)smb_data;
+
+    if ((const uint8_t*)smb_tree_disconnect_hdr + SMB2_TREE_DISCONNECT_STRUC_SIZE > end)
+        return;
+
+    structure_size = alignedNtohs(&(smb_tree_disconnect_hdr->structure_size));
+
+    if (structure_size == SMB2_TREE_DISCONNECT_STRUC_SIZE)
+    {
+        DCE2_Smb2RemoveTid(ssd, Smb2Tid(smb_hdr));
+    }
+}
+
+/********************************************************************
+ *
+ * Process create request, first command for a file processing
+ * Update file name
+ *
+ ********************************************************************/
+static void DCE2_Smb2CreateRequest(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
+    Smb2CreateRequestHdr* smb_create_hdr,const uint8_t* end)
+{
+    uint16_t name_offset = alignedNtohs(&(smb_create_hdr->name_offset));
+    DebugMessage(DEBUG_DCE_SMB, "Processing create request command!\n");
+    DCE2_Smb2InitFileTracker(&ssd->ftracker, false, 0);
+
+    if (name_offset > SMB2_HEADER_LENGTH)
+    {
+        uint16_t size;
+        uint8_t* file_data =  (uint8_t*)smb_create_hdr + smb_create_hdr->name_offset -
+            SMB2_HEADER_LENGTH;
+        if (file_data >= end)
+            return;
+        size = alignedNtohs(&(smb_create_hdr->name_length));
+        if (!size || (file_data + size > end))
+            return;
+        if (ssd->ftracker.file_name)
+        {
+            snort_free((void*)ssd->ftracker.file_name);
+        }
+        ssd->ftracker.file_name = DCE2_Smb2GetFileName(file_data, size, true, false);
+        if (ssd->ftracker.file_name)
+            ssd->ftracker.file_name_size = strlen(ssd->ftracker.file_name) + 1;
+    }
+}
+
+/********************************************************************
+ *
+ * Process create response, need to update file id
+ * For downloading, file size is decided here
+ *
+ ********************************************************************/
+static void DCE2_Smb2CreateResponse(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
+    Smb2CreateResponseHdr* smb_create_hdr, const uint8_t*)
+{
+    uint64_t fileId_persistent;
+    uint64_t file_size = UNKNOWN_FILE_SIZE;
+    DebugMessage(DEBUG_DCE_SMB, "Processing create response command!\n");
+
+    fileId_persistent = alignedNtohq((const uint64_t*)(&(smb_create_hdr->fileId_persistent)));
+    ssd->ftracker.fid_v2 = fileId_persistent;
+    if (smb_create_hdr->end_of_file)
+    {
+        file_size = alignedNtohq((const uint64_t*)(&(smb_create_hdr->end_of_file)));
+        DebugFormat(DEBUG_DCE_SMB, "Get file size %lu!\n", file_size);
+        ssd->ftracker.tracker.file.file_size = file_size;
+    }
+
+    if (ssd->ftracker.file_name && ssd->ftracker.file_name_size)
+    {
+// FIXIT-L port file processing
+/*
+        _dpd.fileAPI->file_cache_update_entry(fileCache, (void *)ssd->sd.wire_pkt, ssd->ftracker.fid_v2,
+                (uint8_t *) ssd->ftracker.file_name,  ssd->ftracker.file_name_size, file_size);
+*/
+    }
+    DCE2_Smb2ResetFileName(&(ssd->ftracker));
+}
+
+/********************************************************************
+ *
+ * Process create command
+ *
+ ********************************************************************/
+static void DCE2_Smb2Create(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    uint16_t structure_size;
+    Smb2CreateRequestHdr* smb_create_hdr = (Smb2CreateRequestHdr*)smb_data;
+
+    structure_size = alignedNtohs(&(smb_create_hdr->structure_size));
+
+    /* Using structure size to decide whether it is response or request */
+    if (structure_size == SMB2_CREATE_REQUEST_STRUC_SIZE)
+    {
+        if ((const uint8_t*)smb_create_hdr + SMB2_CREATE_REQUEST_STRUC_SIZE - 1 > end)
+            return;
+        DCE2_Smb2CreateRequest(ssd, smb_hdr, (Smb2CreateRequestHdr*)smb_create_hdr, end);
+    }
+    else if (structure_size == SMB2_CREATE_RESPONSE_STRUC_SIZE)
+    {
+        if ((const uint8_t*)smb_create_hdr + SMB2_CREATE_RESPONSE_STRUC_SIZE -1 > end)
+            return;
+        DCE2_Smb2CreateResponse(ssd, smb_hdr, (Smb2CreateResponseHdr*)smb_create_hdr, end);
+    }
+    else if (structure_size == SMB2_ERROR_RESPONSE_STRUC_SIZE)
+    {
+        Smb2ErrorResponseHdr* smb_err_response_hdr = (Smb2ErrorResponseHdr*)smb_data;
+        if ((const uint8_t*)smb_create_hdr + SMB2_ERROR_RESPONSE_STRUC_SIZE - 1 > end)
+            return;
+        /* client will ignore when byte count is 0 */
+        if (smb_err_response_hdr->byte_count)
+        {
+            /*Response error, clean up request state*/
+            DCE2_Smb2FreeFileName(&(ssd->ftracker));
+        }
+    }
+    else
+    {
+        DebugMessage(DEBUG_DCE_SMB, "Wrong format for smb create command!\n");
+    }
+}
+
+/********************************************************************
+ *
+ * Process close command
+ * For some upload, file_size is decided here.
+ *
+ ********************************************************************/
+static void DCE2_Smb2CloseCmd(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    /* Using structure size to decide whether it is response or request*/
+    uint16_t structure_size;
+    Smb2CloseRequestHdr* smb_close_hdr = (Smb2CloseRequestHdr*)smb_data;
+
+    if ((const uint8_t*)smb_close_hdr + SMB2_CLOSE_REQUEST_STRUC_SIZE > end)
+        return;
+
+    structure_size = alignedNtohs(&(smb_close_hdr->structure_size));
+
+    if ((structure_size == SMB2_CLOSE_REQUEST_STRUC_SIZE) &&
+        !ssd->ftracker.tracker.file.file_size
+        && ssd->ftracker.tracker.file.file_offset)
+    {
+        bool upload = DCE2_SsnFromClient(ssd->sd.wire_pkt) ? true : false;
+        ssd->ftracker.tracker.file.file_size = ssd->ftracker.tracker.file.file_offset;
+// FIXIT-L port file processing
+/*
+        uint64_t fileId_persistent = alignedNtohq((const uint64_t *)(&(smb_close_hdr->fileId_persistent)));
+        _dpd.fileAPI->file_cache_update_entry(fileCache, (void *)ssd->sd.wire_pkt,
+                fileId_persistent, nullptr,  0, ssd->ftracker.tracker.file.file_size);
+*/
+        DCE2_Smb2ProcessFileData(ssd, nullptr, 0, upload);
+    }
+}
+
+/********************************************************************
+ *
+ * Process set info command
+ * For upload, file_size is decided here.
+ *
+ ********************************************************************/
+static void DCE2_Smb2SetInfo(DCE2_SmbSsnData* ssd, const Smb2Hdr*,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    /* Using structure size to decide whether it is response or request*/
+    uint16_t structure_size;
+    Smb2SetInfoRequestHdr* smb_set_info_hdr = (Smb2SetInfoRequestHdr*)smb_data;
+
+    if ((const uint8_t*)smb_set_info_hdr + SMB2_SET_INFO_REQUEST_STRUC_SIZE > end)
+        return;
+
+    structure_size = alignedNtohs(&(smb_set_info_hdr->structure_size));
+
+    if (structure_size == SMB2_SET_INFO_REQUEST_STRUC_SIZE)
+    {
+        uint8_t* file_data =  (uint8_t*)smb_set_info_hdr + SMB2_SET_INFO_REQUEST_STRUC_SIZE - 1;
+        if (smb_set_info_hdr->file_info_class == SMB2_FILE_ENDOFFILE_INFO)
+        {
+            uint64_t file_size = alignedNtohq((const uint64_t*)file_data);
+            DebugFormat(DEBUG_DCE_SMB, "Get file size %lu!\n", file_size);
+            ssd->ftracker.tracker.file.file_size = file_size;
+//FIXIT-L port file processing
+/*
+           uint64_t fileId_persistent = alignedNtohq((const uint64_t *)(&(smb_set_info_hdr->fileId_persistent)));
+            _dpd.fileAPI->file_cache_update_entry(fileCache, (void *)ssd->sd.wire_pkt,
+                    fileId_persistent, nullptr,  0, file_size);
+*/
+        }
+    }
+}
+
+/********************************************************************
+ *
+ * Process read request
+ *
+ ********************************************************************/
+static void DCE2_Smb2ReadRequest(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    Smb2ReadRequestHdr* smb_read_hdr, const uint8_t*)
+{
+    uint64_t message_id, offset;
+    uint64_t fileId_persistent;
+    DebugMessage(DEBUG_DCE_SMB, "Processing read request command!\n");
+    message_id = alignedNtohq((const uint64_t*)(&(smb_hdr->message_id)));
+    offset = alignedNtohq((const uint64_t*)(&(smb_read_hdr->offset)));
+    fileId_persistent = alignedNtohq((const uint64_t*)(&(smb_read_hdr->fileId_persistent)));
+    DCE2_Smb2StoreRequest(ssd, message_id, offset, fileId_persistent);
+    if (fileId_persistent && (ssd->ftracker.fid_v2 != fileId_persistent))
+    {
+        DebugMessage(DEBUG_DCE_SMB, "Persistent file ID changed read request command!\n");
+        ssd->ftracker.fid_v2 = fileId_persistent;
+    }
+    if (ssd->ftracker.tracker.file.file_size && (offset > ssd->ftracker.tracker.file.file_size))
+    {
+        dce_alert(GID_DCE2, DCE2_SMB_INVALID_FILE_OFFSET, (dce2CommonStats*)&dce2_smb_stats);
+    }
+}
+
+/********************************************************************
+ *
+ * Process read response
+ *
+ ********************************************************************/
+static void DCE2_Smb2ReadResponse(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    Smb2ReadResponseHdr* smb_read_hdr, const uint8_t* end)
+{
+    uint8_t* file_data =  (uint8_t*)smb_read_hdr + SMB2_READ_RESPONSE_STRUC_SIZE - 1;
+    int data_size = end - file_data;
+    uint32_t total_data_length;
+    uint64_t message_id;
+    uint16_t data_offset;
+    Smb2Request* request;
+
+    DebugMessage(DEBUG_DCE_SMB, "Processing read response command!\n");
+
+    message_id = alignedNtohq((const uint64_t*)(&(smb_hdr->message_id)));
+    request = DCE2_Smb2GetRequest(ssd, message_id);
+    if (!request)
+    {
+        return;
+    }
+    data_offset = alignedNtohs((const uint16_t*)(&(smb_read_hdr->data_offset)));
+    if (data_offset + (const uint8_t*)smb_hdr > end)
+    {
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+    }
+
+    ssd->ftracker.tracker.file.file_offset = request->offset;
+    ssd->ftracker.fid_v2 = request->file_id;
+    ssd->ftracker.tracker.file.file_direction = DCE2_SMB_FILE_DIRECTION__DOWNLOAD;
+
+    DCE2_Smb2RemoveRequest(ssd, request);
+
+    DCE2_Smb2ProcessFileData(ssd, file_data, data_size, false);
+    ssd->ftracker.tracker.file.file_offset += data_size;
+    total_data_length = alignedNtohl((const uint32_t*)&(smb_read_hdr->length));
+    if (total_data_length > (uint32_t)data_size)
+        ssd->pdu_state = DCE2_SMB_PDU_STATE__RAW_DATA;
+}
+
+/********************************************************************
+ *
+ * Process read command
+ *
+ ********************************************************************/
+static void DCE2_Smb2Read(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    uint16_t structure_size;
+    Smb2ReadRequestHdr* smb_read_hdr = (Smb2ReadRequestHdr*)smb_data;
+    structure_size = alignedNtohs(&(smb_read_hdr->structure_size));
+
+    /* Using structure size to decide whether it is response or request*/
+    if (structure_size == SMB2_READ_REQUEST_STRUC_SIZE)
+    {
+        if ((const uint8_t*)smb_read_hdr + SMB2_READ_REQUEST_STRUC_SIZE - 1 > end)
+            return;
+        DCE2_Smb2ReadRequest(ssd, smb_hdr, (Smb2ReadRequestHdr*)smb_read_hdr, end);
+    }
+    else if (structure_size == SMB2_READ_RESPONSE_STRUC_SIZE)
+    {
+        if ((const uint8_t*)smb_read_hdr + SMB2_READ_RESPONSE_STRUC_SIZE - 1 > end)
+            return;
+        DCE2_Smb2ReadResponse(ssd, smb_hdr, (Smb2ReadResponseHdr*)smb_read_hdr, end);
+    }
+    else
+    {
+        uint64_t message_id;
+        Smb2Request* request;
+        DebugMessage(DEBUG_DCE_SMB, "Wrong format for smb read command!\n");
+        message_id = alignedNtohq((const uint64_t*)(&(smb_hdr->message_id)));
+        request = DCE2_Smb2GetRequest(ssd, message_id);
+        if (!request)
+        {
+            return;
+        }
+        DCE2_Smb2RemoveRequest(ssd, request);
+    }
+}
+
+/********************************************************************
+ *
+ * Process write request
+ *
+ ********************************************************************/
+static void DCE2_Smb2WriteRequest(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    Smb2WriteRequestHdr* smb_write_hdr, const uint8_t* end)
+{
+    uint8_t* file_data =  (uint8_t*)smb_write_hdr + SMB2_WRITE_REQUEST_STRUC_SIZE - 1;
+    int data_size = end - file_data;
+    uint64_t fileId_persistent, offset;
+    uint16_t data_offset;
+    uint32_t total_data_length;
+
+    DebugMessage(DEBUG_DCE_SMB, "Processing write request command!\n");
+
+    fileId_persistent = alignedNtohq((const uint64_t*)(&(smb_write_hdr->fileId_persistent)));
+    if (fileId_persistent && (ssd->ftracker.fid_v2 != fileId_persistent))
+    {
+        DebugMessage(DEBUG_DCE_SMB, "Persistent file ID changed read request command!\n");
+        ssd->ftracker.fid_v2 = fileId_persistent;
+    }
+    data_offset = alignedNtohs((const uint16_t*)(&(smb_write_hdr->data_offset)));
+    if (data_offset + (const uint8_t*)smb_hdr > end)
+    {
+        dce_alert(GID_DCE2, DCE2_SMB_BAD_OFF, (dce2CommonStats*)&dce2_smb_stats);
+    }
+
+    offset = alignedNtohq((const uint64_t*)(&(smb_write_hdr->offset)));
+    if (ssd->ftracker.tracker.file.file_size && (offset > ssd->ftracker.tracker.file.file_size))
+    {
+        dce_alert(GID_DCE2, DCE2_SMB_INVALID_FILE_OFFSET, (dce2CommonStats*)&dce2_smb_stats);
+    }
+    ssd->ftracker.tracker.file.file_direction = DCE2_SMB_FILE_DIRECTION__UPLOAD;
+    ssd->ftracker.tracker.file.file_offset = offset;
+
+    DCE2_Smb2ProcessFileData(ssd, file_data, data_size, true);
+    ssd->ftracker.tracker.file.file_offset += data_size;
+    total_data_length = alignedNtohl((const uint32_t*)&(smb_write_hdr->length));
+    if (total_data_length > (uint32_t)data_size)
+        ssd->pdu_state = DCE2_SMB_PDU_STATE__RAW_DATA;
+}
+
+/********************************************************************
+ *
+ * Process write response
+ *
+ ********************************************************************/
+static void DCE2_Smb2WriteResponse(DCE2_SmbSsnData*, const Smb2Hdr*,
+    Smb2WriteResponseHdr*, const uint8_t*)
+{
+    DebugMessage(DEBUG_DCE_SMB, "Processing write response command!\n");
+}
+
+/********************************************************************
+ *
+ * Process write command
+ *
+ ********************************************************************/
+static void DCE2_Smb2Write(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr,
+    uint8_t* smb_data, const uint8_t* end)
+{
+    uint16_t structure_size;
+    Smb2WriteRequestHdr* smb_write_hdr = (Smb2WriteRequestHdr*)smb_data;
+    structure_size = alignedNtohs(&(smb_write_hdr->structure_size));
+
+    /* Using structure size to decide whether it is response or request*/
+    if (structure_size == SMB2_WRITE_REQUEST_STRUC_SIZE)
+    {
+        if ((const uint8_t*)smb_write_hdr + SMB2_WRITE_REQUEST_STRUC_SIZE - 1 > end)
+            return;
+        DCE2_Smb2WriteRequest(ssd, smb_hdr, (Smb2WriteRequestHdr*)smb_write_hdr, end);
+    }
+    else if (structure_size == SMB2_WRITE_RESPONSE_STRUC_SIZE)
+    {
+        if ((const uint8_t*)smb_write_hdr + SMB2_WRITE_RESPONSE_STRUC_SIZE - 1 > end)
+            return;
+        DCE2_Smb2WriteResponse(ssd,  smb_hdr, (Smb2WriteResponseHdr*)smb_write_hdr, end);
+    }
+    else
+    {
+        DebugMessage(DEBUG_DCE_SMB, "Wrong format for smb write command!\n");
+    }
+}
+
+/********************************************************************
+ *
+ * Purpose:
+ *  Process SMB2 commands.
+ *
+ * Arguments:
+ *  DCE2_SmbSsnData * - the session data structure.
+ *  const Smb2Hdr *  - pointer to the SMB2 header.
+ *  const uint8_t *  - pointer to end of payload.
+ * Returns: None
+ *
+ ********************************************************************/
+static void DCE2_Smb2Inspect(DCE2_SmbSsnData* ssd, const Smb2Hdr* smb_hdr, const uint8_t* end)
+{
+    uint8_t* smb_data = (uint8_t*)smb_hdr + SMB2_HEADER_LENGTH;
+    uint16_t command = alignedNtohs(&(smb_hdr->command));
+    switch (command)
+    {
+    case SMB2_COM_CREATE:
+        DebugMessage(DEBUG_DCE_SMB, "Create command.\n");
+        dce2_smb_stats.smb2_create++;
+        if (DCE2_Smb2FindTid(ssd, smb_hdr) != DCE2_RET__SUCCESS)
+            return;
+        DCE2_Smb2Create(ssd, smb_hdr, smb_data, end);
+        break;
+    case SMB2_COM_READ:
+        DebugMessage(DEBUG_DCE_SMB, "Read command.\n");
+        dce2_smb_stats.smb2_read++;
+        if (DCE2_Smb2FindTid(ssd, smb_hdr) != DCE2_RET__SUCCESS)
+            return;
+        DCE2_Smb2Read(ssd, smb_hdr, smb_data, end);
+        break;
+    case SMB2_COM_WRITE:
+        DebugMessage(DEBUG_DCE_SMB, "Write command.\n");
+        dce2_smb_stats.smb2_write++;
+        if (DCE2_Smb2FindTid(ssd, smb_hdr) != DCE2_RET__SUCCESS)
+            return;
+        DCE2_Smb2Write(ssd, smb_hdr, smb_data, end);
+        break;
+    case SMB2_COM_SET_INFO:
+        DebugMessage(DEBUG_DCE_SMB, "Set info command.\n");
+        dce2_smb_stats.smb2_set_info++;
+        if (DCE2_Smb2FindTid(ssd, smb_hdr) != DCE2_RET__SUCCESS)
+            return;
+        DCE2_Smb2SetInfo(ssd, smb_hdr, smb_data, end);
+        break;
+    case SMB2_COM_CLOSE:
+        DebugMessage(DEBUG_DCE_SMB, "Close command.\n");
+        dce2_smb_stats.smb2_close++;
+        if (DCE2_Smb2FindTid(ssd, smb_hdr) != DCE2_RET__SUCCESS)
+            return;
+        DCE2_Smb2CloseCmd(ssd, smb_hdr, smb_data, end);
+        break;
+    case SMB2_COM_TREE_CONNECT:
+        DebugMessage(DEBUG_DCE_SMB, "Tree connect command.\n");
+        dce2_smb_stats.smb2_tree_connect++;
+        DCE2_Smb2TreeConnect(ssd, smb_hdr, smb_data, end);
+        break;
+    case SMB2_COM_TREE_DISCONNECT:
+        DebugMessage(DEBUG_DCE_SMB, "Tree disconnect command.\n");
+        dce2_smb_stats.smb2_tree_disconnect++;
+        DCE2_Smb2TreeDisconnect(ssd, smb_hdr, smb_data, end);
+        break;
+    default:
+        DebugMessage(DEBUG_DCE_SMB, "command ignored!\n");
+        break;
+    }
+}
+
+// This is the main entry point for SMB2 processing.
+void DCE2_Smb2Process(DCE2_SmbSsnData* ssd)
+{
+    Packet* p = ssd->sd.wire_pkt;
+    const uint8_t* data_ptr = p->data;
+    uint16_t data_len = p->dsize;
+    Smb2Hdr* smb_hdr;
+    const uint8_t* end = data_ptr +  data_len;
+
+    /*Check header length*/
+    if (data_len < sizeof(NbssHdr) + SMB2_HEADER_LENGTH)
+        return;
+
+    if (!ssd->ftracker.is_smb2)
+    {
+        DCE2_Smb2InitFileTracker(&(ssd->ftracker), 0, 0);
+    }
+
+    /* Process the header */
+    if (p->is_pdu_start())
+    {
+        uint32_t next_command_offset;
+        smb_hdr = (Smb2Hdr*)(data_ptr + sizeof(NbssHdr));
+        next_command_offset = alignedNtohl(&(smb_hdr->next_command));
+        if (next_command_offset + sizeof(NbssHdr) > p->dsize)
+        {
+            dce_alert(GID_DCE2, DCE2_SMB_BAD_NEXT_COMMAND_OFFSET,
+                (dce2CommonStats*)&dce2_smb_stats);
+        }
+        DCE2_Smb2Inspect(ssd, (Smb2Hdr*)smb_hdr, end);
+    }
+    else if (ssd->pdu_state == DCE2_SMB_PDU_STATE__RAW_DATA)
+    {
+        /*continue processing raw data*/
+        bool upload = DCE2_SsnFromClient(ssd->sd.wire_pkt) ? true : false;
+        DCE2_Smb2ProcessFileData(ssd, data_ptr, data_len, upload);
+        ssd->ftracker.tracker.file.file_offset += data_len;
+    }
+}
+
+/* Initialize smb2 file tracker */
+DCE2_Ret DCE2_Smb2InitFileTracker(DCE2_SmbFileTracker* ftracker,
+    const bool is_ipc, const uint64_t fid)
+{
+    if (ftracker == nullptr)
+        return DCE2_RET__ERROR;
+
+    DCE2_Smb2FreeFileName(ftracker);
+    ftracker->fid_v2 = fid;
+    ftracker->is_ipc = is_ipc;
+    ftracker->is_smb2 = true;
+
+    ftracker->ff_file_size = 0;
+    ftracker->ff_file_offset = 0;
+    ftracker->ff_file_direction = DCE2_SMB_FILE_DIRECTION__UNKNOWN;
+
+    return DCE2_RET__SUCCESS;
+}
+
+/* Check whether the packet is smb2 */
+DCE2_SmbVersion DCE2_Smb2Version(const Packet* p)
+{
+    /* Only check reassembled SMB2 packet*/
+    if (p->has_paf_payload() &&
+        (p->dsize > sizeof(NbssHdr) + sizeof(DCE2_SMB_ID)))
+    {
+        Smb2Hdr* smb_hdr = (Smb2Hdr*)(p->data + sizeof(NbssHdr));
+        uint32_t smb_version_id = SmbId((SmbNtHdr*)smb_hdr);
+        if (smb_version_id == DCE2_SMB_ID)
+            return DCE2_SMB_VERISON_1;
+        else if (smb_version_id == DCE2_SMB2_ID)
+            return DCE2_SMB_VERISON_2;
+    }
+
+    return DCE2_SMB_VERISON_NULL;
+}
+
+void DCE2_Smb2CleanRequests(Smb2Request* requests)
+{
+    Smb2Request* request = requests;
+    while (request)
+    {
+        Smb2Request* next;
+        next = request->next;
+        snort_free((void*)request);
+        request = next;
+    }
+}
+
diff --git a/src/service_inspectors/dce_rpc/dce_smb2.h b/src/service_inspectors/dce_rpc/dce_smb2.h
new file mode 100644 (file)
index 0000000..70e63ff
--- /dev/null
@@ -0,0 +1,278 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-2016 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.
+//--------------------------------------------------------------------------
+
+// SMB2 file processing
+// Author(s):  Hui Cao <huica@cisco.com>
+
+#ifndef _DCE_SMB2_H_
+#define _DCE_SMB2_H_
+
+#include "dce_smb.h"
+#include "dce_utils.h"
+
+#define SMB2_FLAGS_ASYNC_COMMAND  0x00000002
+
+struct Smb2Hdr
+{
+    uint8_t smb_idf[4];       /* contains 0xFE,’SMB’ */
+    uint16_t structure_size;  /* This MUST be set to 64 */
+    uint16_t credit_charge;   /* # of credits that this request consumes */
+    uint32_t status;          /* depends */
+    uint16_t command;         /* command code  */
+    uint16_t credit;          /* # of credits requesting/granted */
+    uint32_t flags;           /* flags */
+    uint32_t next_command;    /* used for compounded request */
+    uint64_t message_id;      /* identifies a message uniquely on connection */
+    uint64_t async_sync;      /* used for async and sync differently */
+    uint64_t session_id;      /* identifies the established session for the command*/
+    uint8_t signature[16];    /* signature of the message */
+};
+
+struct Smb2ASyncHdr
+{
+    uint8_t smb_idf[4];       /* contains 0xFE,’SMB’ */
+    uint16_t structure_size;  /* This MUST be set to 64 */
+    uint16_t credit_charge;   /* # of credits that this request consumes */
+    uint32_t status;          /* depends */
+    uint16_t command;         /* command code  */
+    uint16_t credit;          /* # of credits requesting/granted */
+    uint32_t flags;           /* flags */
+    uint32_t next_command;    /* used for compounded request */
+    uint64_t message_id;      /* identifies a message uniquely on connection */
+    uint64_t async_id;        /* handle operations asynchronously */
+    uint64_t session_id;      /* identifies the established session for the command*/
+    uint8_t signature[16];    /* signature of the message */
+};
+
+struct Smb2SyncHdr
+{
+    uint8_t smb_idf[4];       /* contains 0xFE,’SMB’ */
+    uint16_t structure_size;  /* This MUST be set to 64 */
+    uint16_t credit_charge;   /* # of credits that this request consumes */
+    uint32_t status;          /* depends */
+    uint16_t command;         /* command code  */
+    uint16_t credit;          /* # of credits requesting/granted */
+    uint32_t flags;           /* flags */
+    uint32_t next_command;    /* used for compounded request */
+    uint64_t message_id;      /* identifies a message uniquely on connection */
+    uint32_t reserved;        /* reserved */
+    uint32_t tree_id;         /* identifies the tree connect for the command */
+    uint64_t session_id;      /* identifies the established session for the command*/
+    uint8_t signature[16];    /* signature of the message */
+};
+
+struct Smb2ErrorResponseHdr
+{
+    uint16_t structure_size;  /* This MUST be set to 9 */
+    uint16_t reserved;        /* reserved */
+    uint32_t byte_count;      /* The number of bytes of error_data */
+    uint8_t error_data[1];    /* If byte_count is 0, this MUST be 0*/
+};
+
+/* SMB2 command codes */
+#define SMB2_COM_NEGOTIATE        0x00
+#define SMB2_COM_SESSION_SETUP    0x01
+#define SMB2_COM_LOGOFF           0x02
+#define SMB2_COM_TREE_CONNECT     0x03
+#define SMB2_COM_TREE_DISCONNECT  0x04
+#define SMB2_COM_CREATE           0x05
+#define SMB2_COM_CLOSE            0x06
+#define SMB2_COM_FLUSH            0x07
+#define SMB2_COM_READ             0x08
+#define SMB2_COM_WRITE            0x09
+#define SMB2_COM_LOCK             0x0A
+#define SMB2_COM_IOCTL            0x0B
+#define SMB2_COM_CANCEL           0x0C
+#define SMB2_COM_ECHO             0x0D
+#define SMB2_COM_QUERY_DIRECTORY  0x0E
+#define SMB2_COM_CHANGE_NOTIFY    0x0F
+#define SMB2_COM_QUERY_INFO       0x10
+#define SMB2_COM_SET_INFO         0x11
+#define SMB2_COM_OPLOCK_BREAK     0x12
+
+struct Smb2WriteRequestHdr
+{
+    uint16_t structure_size;  /* This MUST be set to 49 */
+    uint16_t data_offset;     /* offset in bytes from the beginning of smb2 header */
+    uint32_t length;          /* length of data being written in bytes */
+    uint64_t offset;          /* offset in the destination file */
+    uint64_t fileId_persistent;  /* fileId that is persistent */
+    uint64_t fileId_volatile;    /* fileId that is volatile */
+    uint32_t channel;            /* channel */
+    uint32_t remaining_bytes;    /* subsequent bytes the client intends to write*/
+    uint16_t write_channel_info_offset;      /* channel data info */
+    uint16_t write_channel_info_length;      /* channel data info */
+    uint32_t flags;      /* flags*/
+};
+
+struct Smb2WriteResponseHdr
+{
+    uint16_t structure_size;  /* This MUST be set to 17 */
+    uint16_t reserved;        /* reserved */
+    uint32_t count;           /* The number of bytes written */
+    uint32_t remaining;       /* MUST be 0*/
+    uint16_t write_channel_info_offset;      /* channel data info */
+    uint16_t write_channel_info_length;      /* channel data info */
+};
+
+struct Smb2ReadRequestHdr
+{
+    uint16_t structure_size;  /* This MUST be set to 49 */
+    uint8_t padding;          /* Padding */
+    uint8_t flags;            /* Flags */
+    uint32_t length;          /* length of data to read from the file */
+    uint64_t offset;          /* offset in the destination file */
+    uint64_t fileId_persistent;  /* fileId that is persistent */
+    uint64_t fileId_volatile;    /* fileId that is volatile */
+    uint32_t minimum_count;      /* The minimum # of bytes to be read */
+    uint32_t channel;            /* channel */
+    uint32_t remaining_bytes;    /* subsequent bytes the client intends to read*/
+    uint16_t read_channel_info_offset;      /* channel data info */
+    uint16_t read_channel_info_length;      /* channel data info */
+};
+
+struct Smb2ReadResponseHdr
+{
+    uint16_t structure_size; /* This MUST be set to 17 */
+    uint8_t data_offset;     /* offset in bytes from beginning of smb2 header*/
+    uint8_t reserved;        /* reserved */
+    uint32_t length;         /* The number of bytes being returned in response */
+    uint32_t remaining;      /* The number of data being sent on the channel*/
+    uint32_t reserved2;      /* reserved */
+};
+
+struct Smb2SetInfoRequestHdr
+{
+    uint16_t structure_size;   /* This MUST be set to 33 */
+    uint8_t info_type;         /* info type */
+    uint8_t file_info_class;   /* file info class after header */
+    uint32_t buffer_length;    /* buffer length */
+    uint16_t buffer_offset;    /* buffer offset */
+    uint16_t reserved;         /* reserved */
+    uint32_t additional_info;  /* additional information */
+    uint64_t fileId_persistent;/* fileId that is persistent */
+    uint64_t fileId_volatile;  /* fileId that is volatile */
+};
+
+struct Smb2CreateRequestHdr
+{
+    uint16_t structure_size;          /* This MUST be set to 57 */
+    uint8_t security_flags;           /* security flag, should be 0 */
+    uint8_t requested_oplock_level;   /* */
+    uint32_t impersonation_level;     /* */
+    uint64_t smb_create_flags;        /* should be 0 */
+    uint64_t reserved;                /* can be any value */
+    uint32_t desired_access;          /*  */
+    uint32_t file_attributes;         /* */
+    uint32_t share_access;            /* READ WRITE DELETE etc */
+    uint32_t create_disposition;      /* actions when file exists*/
+    uint32_t create_options;          /* options for creating file*/
+    uint16_t name_offset;             /* file name offset from SMB2 header */
+    uint16_t name_length;             /* length of file name */
+    uint32_t create_contexts_offset;  /* offset of contexts from beginning of header */
+    uint32_t create_contexts_length;  /* length of contexts */
+};
+
+struct Smb2CreateResponseHdr
+{
+    uint16_t structure_size;          /* This MUST be set to 89 */
+    uint8_t oplock_level;             /* oplock level granted, values limited */
+    uint8_t flags;                    /* flags, values limited */
+    uint32_t create_action;           /* action taken, values limited */
+    uint64_t creation_time;           /* time created */
+    uint64_t last_access_time;        /* access time */
+    uint64_t last_write_time;         /* write  time */
+    uint64_t change_time;             /* time modified*/
+    uint64_t allocation_size;         /* size allocated */
+    uint64_t end_of_file;             /* file size*/
+    uint32_t file_attributes;         /* attributes of the file*/
+    uint32_t reserved2;               /* */
+    uint64_t fileId_persistent;       /* fileId that is persistent */
+    uint64_t fileId_volatile;         /* fileId that is volatile */
+    uint32_t create_contexts_offset;  /*  */
+    uint32_t create_contexts_length;  /*  */
+};
+
+struct Smb2CloseRequestHdr
+{
+    uint16_t structure_size;          /* This MUST be set to 24 */
+    uint16_t flags;                   /* flags */
+    uint32_t reserved;                /* can be any value */
+    uint64_t fileId_persistent;       /* fileId that is persistent */
+    uint64_t fileId_volatile;         /* fileId that is volatile */
+};
+
+#define SMB2_SHARE_TYPE_DISK  0x01
+#define SMB2_SHARE_TYPE_PIPE  0x02
+#define SMB2_SHARE_TYPE_PRINT 0x03
+
+struct Smb2TreeConnectResponseHdr
+{
+    uint16_t structure_size;          /* This MUST be set to 16 */
+    uint8_t share_type;               /* type of share being accessed */
+    uint8_t reserved;                 /* reserved */
+    uint32_t share_flags;             /* properties for this share*/
+    uint32_t capabilities;            /* various capabilities for this share */
+    uint32_t maximal_access;          /* maximal access for the user */
+};
+
+struct Smb2TreeDisConnectHdr
+{
+    uint16_t structure_size;          /* This MUST be set to 4 */
+    uint16_t reserved;                 /* reserved */
+};
+
+#define SMB2_HEADER_LENGTH 64
+
+#define SMB2_ERROR_RESPONSE_STRUC_SIZE 9
+
+#define SMB2_CREATE_REQUEST_STRUC_SIZE 57
+#define SMB2_CREATE_RESPONSE_STRUC_SIZE 89
+#define SMB2_CREATE_REQUEST_DATA_OFFSET 120
+
+#define SMB2_CLOSE_REQUEST_STRUC_SIZE 24
+
+#define SMB2_WRITE_REQUEST_STRUC_SIZE 49
+#define SMB2_WRITE_RESPONSE_STRUC_SIZE 17
+
+#define SMB2_READ_REQUEST_STRUC_SIZE 49
+#define SMB2_READ_RESPONSE_STRUC_SIZE 17
+
+#define SMB2_SET_INFO_REQUEST_STRUC_SIZE 33
+#define SMB2_SET_INFO_RESPONSE_STRUC_SIZE 2
+
+#define SMB2_TREE_CONNECT_RESPONSE_STRUC_SIZE 16
+#define SMB2_TREE_DISCONNECT_STRUC_SIZE 4
+
+#define SMB2_FILE_ENDOFFILE_INFO 0x14
+
+/* Clean up all the pending requests*/
+void DCE2_Smb2CleanRequests(Smb2Request* requests);
+
+/* Process smb2 message */
+void DCE2_Smb2Process(DCE2_SmbSsnData* ssd);
+
+/* Initialize file tracker for smb2 processing */
+DCE2_Ret DCE2_Smb2InitFileTracker(DCE2_SmbFileTracker* ftracker,
+    const bool is_ipc, const uint64_t fid);
+
+/* Check smb version based on smb header */
+DCE2_SmbVersion DCE2_Smb2Version(const Packet* p);
+
+#endif  /* _DCE_SMB2_H_ */
+
index ddf463eb4d1651e3112b9bddcb65fdf37f6a598e..0dea0d39d664c9821dcdc67feba0509357ef9492 100644 (file)
@@ -70,10 +70,18 @@ static const PegInfo dce2_smb_pegs[] =
       "total connection-oriented server fragments reassembled" },
     { "Sessions", "total smb sessions" },
     { "Packets", "total smb packets" },
+    { "Ignored bytes", "total ignored bytes" },
     { "Client segs reassembled", "total smb client segments reassembled" },
     { "Server segs reassembled", "total smb server segments reassembled" },
     { "Max outstanding requests", "total smb maximum outstanding requests" },
     { "Files processed", "total smb files processed" },
+    { "SMBv2 create", "total number of SMBv2 create packets seen" },
+    { "SMBv2 write", "total number of SMBv2 write packets seen" },
+    { "SMBv2 read", "total number of SMBv2 read packets seen" },
+    { "SMBv2 set info", "total number of SMBv2 set info packets seen" },
+    { "SMBv2 tree connect", "total number of SMBv2 tree connect packets seen" },
+    { "SMBv2 tree disconnect", "total number of SMBv2 tree disconnect packets seen" },
+    { "SMBv2 close", "total number of SMBv2 close packets seen" },
     { nullptr, nullptr }
 };
 
@@ -109,7 +117,8 @@ static const Parameter s_params[] =
       " SMB file depth for file data" },
     { "smb_invalid_shares", Parameter::PT_STRING, nullptr, nullptr,
       "SMB shares to alert on " },
-
+    { "smb_legacy_mode", Parameter::PT_BOOL, nullptr, "false",
+      "inspect only SMBv1" },
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
@@ -166,6 +175,8 @@ static const RuleMap dce2_smb_rules[] =
     { DCE2_SMB_INVALID_SETUP_COUNT, DCE2_SMB_INVALID_SETUP_COUNT_STR },
     { DCE2_SMB_MULTIPLE_NEGOTIATIONS, DCE2_SMB_MULTIPLE_NEGOTIATIONS_STR },
     { DCE2_SMB_EVASIVE_FILE_ATTRS, DCE2_SMB_EVASIVE_FILE_ATTRS_STR },
+    { DCE2_SMB_INVALID_FILE_OFFSET, DCE2_SMB_INVALID_FILE_OFFSET_STR },
+    { DCE2_SMB_BAD_NEXT_COMMAND_OFFSET, DCE2_SMB_BAD_NEXT_COMMAND_OFFSET_STR },
     { 0, nullptr }
 };
 
@@ -438,6 +449,8 @@ bool Dce2SmbModule::set(const char*, Value& v, SnortConfig*)
         config.smb_file_depth = v.get_long();
     else if ( v.is("smb_invalid_shares") )
         return(set_smb_invalid_shares(config,v));
+    else if ( v.is("smb_legacy_mode"))
+        config.legacy_mode = v.get_bool();
     else
         return false;
     return true;
@@ -517,5 +530,7 @@ void print_dce2_smb_conf(dce2SmbProtoConf& config)
             LogMessage("    %s\n",share->ascii_str);
         }
     }
+    if (config.legacy_mode)
+        LogMessage("    SMB legacy mode enabled\n");
 }
 
index 83ecb792ce781be213e1543366fe02e63e2559ae..ca7dfc9cbda043eb8415fad58e0a92fa4d7de45b 100644 (file)
@@ -64,6 +64,7 @@ struct dce2SmbProtoConf
     dce2SmbFileInspection smb_file_inspection;
     int16_t smb_file_depth;
     DCE2_List* smb_invalid_shares;
+    bool legacy_mode;
 };
 
 class Dce2SmbModule : public Module
@@ -143,5 +144,12 @@ inline bool DCE2_GcSmbFingerprintServer(const dce2SmbProtoConf* sc)
            & DCE2_SMB_FINGERPRINT_POLICY_SERVER ? true : false;
 }
 
+inline bool DCE2_GcIsLegacyMode(const dce2SmbProtoConf* sc)
+{
+    if (sc == nullptr)
+        return false;
+    return sc->legacy_mode;
+}
+
 #endif
 
index d7f08e4cfa257f87b617956675e6d451e7a08c87..e4bd70e35199e4eb096588b58a348d86010ee7e8 100644 (file)
@@ -33,7 +33,6 @@
 /********************************************************************
  * Private function prototypes
  ********************************************************************/
-static void DCE2_FileDetect();
 static void DCE2_SmbSetNewFileAPIFileTracker(DCE2_SmbSsnData* ssd);
 static void DCE2_SmbResetFileChunks(DCE2_SmbFileTracker* ssd);
 static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd);
@@ -240,8 +239,8 @@ void DCE2_SmbRemoveUid(DCE2_SmbSsnData* ssd, const uint16_t uid)
     case DCE2_POLICY__SAMBA:
     case DCE2_POLICY__SAMBA_3_0_37:
         // Removing uid invalidates any fid that was created with it */
-        if ((ssd->ftracker.fid != DCE2_SENTINEL) &&
-            (ssd->ftracker.uid == uid))
+        if ((ssd->ftracker.fid_v1 != DCE2_SENTINEL) &&
+            (ssd->ftracker.uid_v1 == uid))
         {
             DCE2_SmbRemoveFileTracker(ssd, &ssd->ftracker);
         }
@@ -254,7 +253,7 @@ void DCE2_SmbRemoveUid(DCE2_SmbSsnData* ssd, const uint16_t uid)
                 ftracker != nullptr;
                 ftracker = (DCE2_SmbFileTracker*)DCE2_ListNext(ssd->ftrackers))
             {
-                if (ftracker->uid == uid)
+                if (ftracker->uid_v1 == uid)
                 {
                     if (ssd->fapi_ftracker == ftracker)
                         DCE2_SmbFinishFileAPI(ssd);
@@ -391,7 +390,7 @@ DCE2_SmbFileTracker* DCE2_SmbNewFileTracker(DCE2_SmbSsnData* ssd,
         "with Uid: %hu, Tid: %hu, Fid: 0x%04X\n", uid, tid, fid);
 
     DCE2_SmbFileTracker* ftracker = nullptr;
-    if (ssd->ftracker.fid == DCE2_SENTINEL)
+    if (ssd->ftracker.fid_v1 == DCE2_SENTINEL)
     {
         ftracker = &ssd->ftracker;
         if (DCE2_SmbInitFileTracker(ssd, ftracker, is_ipc, uid, tid, (int)fid) !=
@@ -449,11 +448,13 @@ DCE2_Ret DCE2_SmbInitFileTracker(DCE2_SmbSsnData* ssd,
     if (ftracker == nullptr)
         return DCE2_RET__ERROR;
 
-    ftracker->uid = uid;
-    ftracker->tid = tid;
-    ftracker->fid = fid;
+    ftracker->uid_v1 = uid;
+    ftracker->tid_v1 = tid;
+    ftracker->fid_v1 = fid;
     ftracker->is_ipc = is_ipc;
+    ftracker->is_smb2 = false;
     ftracker->file_name = nullptr;
+    ftracker->file_name_size = 0;
     if (is_ipc)
     {
         DCE2_CoTracker* co_tracker = (DCE2_CoTracker*)snort_calloc(sizeof(DCE2_CoTracker));
@@ -493,7 +494,7 @@ DCE2_SmbFileTracker* DCE2_SmbFindFileTracker(DCE2_SmbSsnData* ssd,
         "Uid: %hu, Tid: %hu, Fid: 0x%04X ... ", uid, tid, fid);
 
     DCE2_SmbFileTracker* ftracker;
-    if ((ssd->ftracker.fid != DCE2_SENTINEL) && (ssd->ftracker.fid == (int)fid))
+    if ((ssd->ftracker.fid_v1 != DCE2_SENTINEL) && (ssd->ftracker.fid_v1 == (int)fid))
     {
         ftracker = &ssd->ftracker;
     }
@@ -516,7 +517,7 @@ DCE2_SmbFileTracker* DCE2_SmbFindFileTracker(DCE2_SmbSsnData* ssd,
     case DCE2_POLICY__SAMBA:
     case DCE2_POLICY__SAMBA_3_0_37:
         // Only Uid used to open file can be used to make a request
-        if (ftracker->uid != uid)
+        if (ftracker->uid_v1 != uid)
         {
             DebugMessage(DEBUG_DCE_SMB, "Not found.\n");
             return nullptr;
@@ -549,7 +550,7 @@ DCE2_SmbFileTracker* DCE2_SmbFindFileTracker(DCE2_SmbSsnData* ssd,
     case DCE2_POLICY__WIN2008:
     case DCE2_POLICY__WIN7:
         // Both Uid and Tid used to create file must be used to make a request
-        if ((ftracker->uid != uid) || (ftracker->tid != tid))
+        if ((ftracker->uid_v1 != uid) || (ftracker->tid_v1 != tid))
         {
             DebugMessage(DEBUG_DCE_SMB, "Not found.\n");
             return nullptr;
@@ -565,7 +566,7 @@ DCE2_SmbFileTracker* DCE2_SmbFindFileTracker(DCE2_SmbSsnData* ssd,
 
     DebugFormat(DEBUG_DCE_SMB, "Found with "
         "Uid: %hu, Tid: %hu, Fid: 0x%04X\n",
-        ftracker->uid, ftracker->tid, ftracker->fid);
+        ftracker->uid_v1, ftracker->tid_v1, ftracker->fid_v1);
     return ftracker;
 }
 
@@ -606,7 +607,7 @@ void DCE2_SmbRemoveFileTracker(DCE2_SmbSsnData* ssd, DCE2_SmbFileTracker* ftrack
     Profile profile(dce2_smb_pstat_smb_fid);
 
     DebugFormat(DEBUG_DCE_SMB,
-        "Removing file tracker with Fid: 0x%04X\n", ftracker->fid);
+        "Removing file tracker with Fid: 0x%04X\n", ftracker->fid_v1);
 
     if (ssd->fapi_ftracker == ftracker)
         DCE2_SmbFinishFileAPI(ssd);
@@ -621,7 +622,7 @@ void DCE2_SmbRemoveFileTracker(DCE2_SmbSsnData* ssd, DCE2_SmbFileTracker* ftrack
     if (ftracker == &ssd->ftracker)
         DCE2_SmbCleanFileTracker(&ssd->ftracker);
     else if (ssd->ftrackers != nullptr)
-        DCE2_ListRemove(ssd->ftrackers, (void*)(uintptr_t)ftracker->fid);
+        DCE2_ListRemove(ssd->ftrackers, (void*)(uintptr_t)ftracker->fid_v1);
 
     DCE2_SmbRemoveFileTrackerFromRequestTrackers(ssd, ftracker);
 }
@@ -633,11 +634,12 @@ void DCE2_SmbCleanFileTracker(DCE2_SmbFileTracker* ftracker)
 
     Profile profile(dce2_smb_pstat_smb_fid);
 
-    ftracker->fid = DCE2_SENTINEL;
+    ftracker->fid_v1 = DCE2_SENTINEL;
     if (ftracker->file_name != nullptr)
     {
         snort_free((void*)ftracker->file_name);
         ftracker->file_name = nullptr;
+        ftracker->file_name_size = 0;
     }
 
     if (ftracker->is_ipc)
@@ -684,7 +686,7 @@ void DCE2_SmbFileTrackerDataFree(void* data)
 
     DebugFormat(DEBUG_DCE_SMB, "Freeing file tracker: "
         "Uid: %hu, Tid: %hu, Fid: 0x%04X\n",
-        ftracker->uid, ftracker->tid, ftracker->fid);
+        ftracker->uid_v1, ftracker->tid_v1, ftracker->fid_v1);
 
     DCE2_SmbCleanFileTracker(ftracker);
     snort_free((void*)ftracker);
@@ -831,7 +833,7 @@ DCE2_SmbFileTracker* DCE2_SmbDequeueTmpFileTracker(DCE2_SmbSsnData* ssd,
         return nullptr;
     }
 
-    if (ssd->ftracker.fid == DCE2_SENTINEL)
+    if (ssd->ftracker.fid_v1 == DCE2_SENTINEL)
     {
         memcpy(&ssd->ftracker, ftracker, sizeof(DCE2_SmbFileTracker));
         snort_free((void*)ftracker);
@@ -863,7 +865,7 @@ DCE2_SmbFileTracker* DCE2_SmbDequeueTmpFileTracker(DCE2_SmbSsnData* ssd,
     }
 
     // Other values were intialized when queueing.
-    ftracker->fid = (int)fid;
+    ftracker->fid_v1 = (int)fid;
 
     return ftracker;
 }
@@ -909,8 +911,8 @@ void DCE2_SmbRemoveTid(DCE2_SmbSsnData* ssd, const uint16_t tid)
         DCE2_ListRemove(ssd->tids, (void*)(uintptr_t)tid);
 
     // Removing Tid invalidates files created with it
-    if ((ssd->ftracker.fid != DCE2_SENTINEL)
-        && (ssd->ftracker.tid == tid))
+    if ((ssd->ftracker.fid_v1 != DCE2_SENTINEL)
+        && (ssd->ftracker.tid_v1 == tid))
     {
         DCE2_SmbRemoveFileTracker(ssd, &ssd->ftracker);
     }
@@ -923,7 +925,7 @@ void DCE2_SmbRemoveTid(DCE2_SmbSsnData* ssd, const uint16_t tid)
             ftracker != nullptr;
             ftracker = (DCE2_SmbFileTracker*)DCE2_ListNext(ssd->ftrackers))
         {
-            if (ftracker->tid == (int)tid)
+            if (ftracker->tid_v1 == (int)tid)
             {
                 if (ssd->fapi_ftracker == ftracker)
                     DCE2_SmbFinishFileAPI(ssd);
@@ -1112,7 +1114,7 @@ DCE2_Ret DCE2_SmbProcessRequestData(DCE2_SmbSsnData* ssd,
         return DCE2_RET__ERROR;
 
     DebugFormat(DEBUG_DCE_SMB,
-        "Processing request data with Fid: 0x%04X ~~~~~~~~~~~~~~~~~\n", ftracker->fid);
+        "Processing request data with Fid: 0x%04X ~~~~~~~~~~~~~~~~~\n", ftracker->fid_v1);
 
     // Set this in case of chained commands or reassembled packet
     ssd->cur_rtracker->ftracker = ftracker;
@@ -1148,7 +1150,7 @@ DCE2_Ret DCE2_SmbProcessResponseData(DCE2_SmbSsnData* ssd,
         return DCE2_RET__ERROR;
 
     DebugFormat(DEBUG_DCE_SMB,
-        "Processing response data with Fid: 0x%04X ~~~~~~~~~~~~~~~~\n", ftracker->fid);
+        "Processing response data with Fid: 0x%04X ~~~~~~~~~~~~~~~~\n", ftracker->fid_v1);
 
     if (ftracker->is_ipc)
     {
@@ -1271,9 +1273,9 @@ void DCE2_SmbSetRdata(DCE2_SmbSsnData* ssd, uint8_t* nb_ptr, uint16_t co_len)
 
         nb_hdr->length = htons((uint16_t)nb_len);
 
-        if ((ftracker != nullptr) && (ftracker->fid > 0))
+        if ((ftracker != nullptr) && (ftracker->fid_v1 > 0))
         {
-            uint16_t fid = (uint16_t)ftracker->fid;
+            uint16_t fid = (uint16_t)ftracker->fid_v1;
             writex->smb_fid = SmbHtons(&fid);
         }
         else
@@ -1598,7 +1600,7 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd,
     {
         DebugFormat(DEBUG_DCE_SMB, "File API returned FAILURE "
             "for \"%s\" (0x%02X) %s\n", ftracker->file_name,
-            ftracker->fid, upload ? "UPLOAD" : "DOWNLOAD");
+            ftracker->fid_v1, upload ? "UPLOAD" : "DOWNLOAD");
 
         // Failure.  Abort tracking this file under file API
         return DCE2_RET__ERROR;
@@ -1607,7 +1609,7 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd,
     {
         DebugFormat(DEBUG_DCE_SMB, "File API returned SUCCESS "
             "for \"%s\" (0x%02X) %s\n", ftracker->file_name,
-            ftracker->fid, upload ? "UPLOAD" : "DOWNLOAD");
+            ftracker->fid_v1, upload ? "UPLOAD" : "DOWNLOAD");
 
         if (((position == SNORT_FILE_START) || (position == SNORT_FILE_FULL))
             && (strlen(ftracker->file_name) != 0))
@@ -1745,7 +1747,7 @@ static DCE2_Ret DCE2_SmbHandleOutOfOrderFileData(DCE2_SmbSsnData* ssd,
                 (void*)file_chunk, (void*)file_chunk)) != DCE2_RET__SUCCESS)
         {
             DebugFormat(DEBUG_DCE_SMB, "Insert file chunk failed: "
-                "0x%02X.\n", ftracker->fid);
+                "0x%02X.\n", ftracker->fid_v1);
 
             snort_free((void*)file_chunk->data);
             snort_free((void*)file_chunk);
@@ -1926,7 +1928,7 @@ void DCE2_SmbProcessFileData(DCE2_SmbSsnData* ssd,
     }
 }
 
-static void DCE2_FileDetect()
+void DCE2_FileDetect()
 {
     Packet* top_pkt = (Packet*)DCE2_CStackTop(dce2_pkt_stack);
     if (top_pkt == nullptr)
@@ -1956,13 +1958,13 @@ static void DCE2_SmbSetNewFileAPIFileTracker(DCE2_SmbSsnData* ssd)
 
     while (ftracker != nullptr)
     {
-        if ((ftracker != ssd->fapi_ftracker) && (ftracker->fid != DCE2_SENTINEL)
+        if ((ftracker != ssd->fapi_ftracker) && (ftracker->fid_v1 != DCE2_SENTINEL)
             && !ftracker->is_ipc && ftracker->ff_sequential_only
             && (ftracker->ff_bytes_processed == 0))
         {
             DebugFormat(DEBUG_DCE_SMB, "Designating file tracker "
                 "for file API processing: \"%s\" (0x%04X)\n",
-                ftracker->file_name, (uint16_t)ftracker->fid);
+                ftracker->file_name, (uint16_t)ftracker->fid_v1);
             break;
         }
 
index cd42e96cd871b98562aa4bd6ee43562839860871..63986acf7d83ec5b65e5e07f868c1fd35d3299e6 100644 (file)
@@ -175,6 +175,7 @@ void DCE2_SmbAbortFileAPI(DCE2_SmbSsnData*);
 void DCE2_SmbProcessFileData(DCE2_SmbSsnData* ssd,
     DCE2_SmbFileTracker* ftracker, const uint8_t* data_ptr,
     uint32_t data_len, bool upload);
+void DCE2_FileDetect();
 
 /********************************************************************
  * Inline functions
index 670c5c8e6371d9c08b9b1174abd6761090d0f795..6b963afb2e5a4647268a0f5a59d27ae82a09d838 100644 (file)
@@ -36,6 +36,7 @@ private:
     bool add_option_to_all(std::string option, const bool val);
     bool add_option_to_all(std::string option, const int val);
     bool add_option_to_type(std::string type, std::string option, std::string value);
+    bool add_option_to_type(std::string type, std::string option);
     bool parse_int_and_add_to_all(std::string opt_name, std::istringstream& stream);
     bool parse_string_and_add_to_type(std::string type, std::string opt_name,
         std::istringstream& stream);
@@ -96,6 +97,18 @@ bool Dcerpc::add_option_to_type(std::string type, std::string option, const std:
     return tmpval;
 }
 
+bool Dcerpc::add_option_to_type(std::string type, std::string option)
+{
+    bool tmpval = add_option_to_table(table_api, "dce_" + type, option, true);
+    for (int i=0; i < DcerpcServer::get_binding_id(); i++)
+    {
+        tmpval = add_option_to_table(table_api, "dce_" + type + std::to_string(i), option, true) &&
+            tmpval;
+    }
+
+    return tmpval;
+}
+
 bool Dcerpc::add_deleted_comment_to_defaults(std::string option)
 {
     bool tmpval = true;
@@ -197,7 +210,7 @@ bool Dcerpc::convert(std::istringstream& data_stream)
             tmpval = parse_string_and_add_to_type("smb", "smb_fingerprint_policy", data_stream);
 
         else if (!keyword.compare("smb_legacy_mode"))
-            tmpval = add_deleted_comment_to_table("dce_smb", "smb_legacy_mode");
+            tmpval = add_option_to_type("smb", "smb_legacy_mode");
         else
         {
             tmpval = false;
index bf4475556af0bb54d40596be5e6af9ae80b655ac..d2b1789d6e4c4b51bee07f5b2029a62190b2e973 100644 (file)
@@ -540,6 +540,13 @@ bool DcerpcServer::init_net_created_table()
             tmpval;
         table_api.open_table("dce_smb");
     }
+    if (table_api.option_exists("smb_legacy_mode"))
+    {
+        table_api.close_table();
+        tmpval = add_option_to_table(table_api,table_name["smb"], "smb_legacy_mode", true) &&
+            tmpval;
+        table_api.open_table("dce_smb");
+    }
     table_api.close_table();
 
     return tmpval;