1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation.  You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // inspector.h author Russ Combs <rucombs@cisco.com>
19 
20 #ifndef INSPECTOR_H
21 #define INSPECTOR_H
22 
23 // Inspectors are the workhorse that do all the heavy lifting between
24 // decoding a packet and detection.  There are several types that operate
25 // in different ways.  These correspond to Snort 2X preprocessors.
26 
27 #include <atomic>
28 
29 #include "framework/base_api.h"
30 #include "main/thread.h"
31 #include "target_based/snort_protocols.h"
32 
33 class Session;
34 
35 namespace snort
36 {
37 struct SnortConfig;
38 struct Packet;
39 
40 // this is the current version of the api
41 #define INSAPI_VERSION ((BASE_API_VERSION << 16) | 0)
42 
43 struct InspectionBuffer
44 {
45     enum Type
46     {
47         // FIXIT-L file data is tbd
48         IBT_KEY, IBT_HEADER, IBT_BODY, IBT_FILE, IBT_ALT,
49         IBT_RAW_KEY, IBT_RAW_HEADER, IBT_METHOD, IBT_STAT_CODE,
50         IBT_STAT_MSG, IBT_COOKIE, IBT_JS_DATA, IBT_VBA, IBT_MAX
51     };
52     const uint8_t* data;
53     unsigned len;
54 };
55 
56 struct InspectApi;
57 
58 //-------------------------------------------------------------------------
59 // api for class
60 //-------------------------------------------------------------------------
61 
62 class SO_PUBLIC Inspector
63 {
64 public:
65     // main thread functions
66     virtual ~Inspector();
67 
68     Inspector(const Inspector&) = delete;
69     Inspector& operator=(const Inspector&) = delete;
70 
71     // access external dependencies here
72     // return verification status
configure(SnortConfig *)73     virtual bool configure(SnortConfig*) { return true; }
74 
75     // cleanup for inspector instance removal from the running configuration
76     // this is only called for inspectors in the default inspection policy that
77     // were present in the prior snort configuration and were removed in the snort
78     // configuration that is being loaded during a reload_config command
tear_down(SnortConfig *)79     virtual void tear_down(SnortConfig*) { }
80 
81     // called on controls after everything is configured
82     // return true if there is nothing to do ever based on config
disable(SnortConfig *)83     virtual bool disable(SnortConfig*) { return false; }
84 
show(const SnortConfig *)85     virtual void show(const SnortConfig*) const { }
86 
87     // Specific to Binders to notify them of an inspector being removed from the policy
88     // FIXIT-L Probably shouldn't be part of the base Inspector class
remove_inspector_binding(SnortConfig *,const char *)89     virtual void remove_inspector_binding(SnortConfig*, const char*) { }
90 
91     // packet thread functions
92     // tinit, tterm called on default policy instance only
tinit()93     virtual void tinit() { }   // allocate configurable thread local
tterm()94     virtual void tterm() { }   // purge only, deallocate via api
95 
96     // screen incoming packets; only liked packets go to eval
97     // default filter is per api proto / paf
98     virtual bool likes(Packet*);
99 
100     // clear is a bookend to eval() for the active service inspector
101     // clear is called when Snort is done with the previously eval'd
102     // packet to release any thread-local or flow-based data
103     virtual void eval(Packet*) = 0;
clear(Packet *)104     virtual void clear(Packet*) { }
105 
106     // framework support
get_ref(unsigned i)107     unsigned get_ref(unsigned i) { return ref_count[i]; }
set_ref(unsigned i,unsigned r)108     void set_ref(unsigned i, unsigned r) { ref_count[i] = r; }
109 
110     void add_ref();
111     void rem_ref();
112 
113     // Reference counts for the inspector that are not thread specific
114     void add_global_ref();
115     void rem_global_ref();
116 
117     bool is_inactive();
118 
set_service(SnortProtocolId snort_protocol_id_param)119     void set_service(SnortProtocolId snort_protocol_id_param)
120     { snort_protocol_id = snort_protocol_id_param; }
121 
get_service()122     SnortProtocolId get_service() const { return snort_protocol_id; }
123 
124     // for well known buffers
125     // well known buffers may be included among generic below,
126     // but they must be accessible from here
get_buf(InspectionBuffer::Type,Packet *,InspectionBuffer &)127     virtual bool get_buf(InspectionBuffer::Type, Packet*, InspectionBuffer&)
128     { return false; }
129 
130     // for generic buffers
131     // key is listed in api buffers
132     // id-1 is zero based index into buffers array
133     unsigned get_buf_id(const char* key);
134     virtual bool get_buf(const char* key, Packet*, InspectionBuffer&);
get_buf(unsigned,Packet *,InspectionBuffer &)135     virtual bool get_buf(unsigned /*id*/, Packet*, InspectionBuffer&)
136     { return false; }
137 
get_fp_buf(InspectionBuffer::Type ibt,Packet * p,InspectionBuffer & bf)138     virtual bool get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& bf)
139     { return get_buf(ibt, p, bf); }
140 
141     // IT_SERVICE only
142     virtual class StreamSplitter* get_splitter(bool to_server);
143 
set_api(const InspectApi * p)144     void set_api(const InspectApi* p)
145     { api = p; }
146 
get_api()147     const InspectApi* get_api()
148     { return api; }
149 
150     const char* get_name() const;
151 
set_alias_name(const char * name)152     void set_alias_name(const char* name)
153     { alias_name = name; }
154 
get_alias_name()155     const char* get_alias_name() const
156     { return alias_name; }
157 
is_control_channel()158     virtual bool is_control_channel() const
159     { return false; }
160 
can_carve_files()161     virtual bool can_carve_files() const
162     { return false; }
163 
can_start_tls()164     virtual bool can_start_tls() const
165     { return false; }
166 
167 public:
168     static unsigned max_slots;
169     static THREAD_LOCAL unsigned slot;
170 
171 protected:
172     // main thread functions
173     Inspector();  // internal init only at this point
174 
175 private:
176     const InspectApi* api = nullptr;
177     std::atomic_uint* ref_count;
178     SnortProtocolId snort_protocol_id = 0;
179     // FIXIT-E Use std::string to avoid storing a pointer to external std::string buffers
180     const char* alias_name = nullptr;
181 };
182 
183 // at present there is no sequencing among like types except that appid
184 // is always first among controls.
185 
186 enum InspectorType
187 {
188     IT_PASSIVE,  // config only, or data consumer (eg file_log, binder, ftp_client)
189     IT_WIZARD,   // guesses service inspector
190     IT_PACKET,   // processes raw packets only (eg normalize, capture)
191     IT_STREAM,   // flow tracking and reassembly (eg ip, tcp, udp)
192     IT_FIRST,    // analyze 1st pkt of new flow and 1st pkt after reload of ongoing flow (eg rep)
193     IT_NETWORK,  // process packets w/o service (eg arp, bo)
194     IT_SERVICE,  // extract and analyze service PDUs (eg dce, http, ssl)
195     IT_CONTROL,  // process all packets before detection (eg appid)
196     IT_PROBE,    // process all packets after detection (eg perf_monitor, port_scan)
197     IT_MAX
198 };
199 
200 typedef Inspector* (* InspectNew)(Module*);
201 typedef void (* InspectDelFunc)(Inspector*);
202 typedef void (* InspectFunc)();
203 typedef Session* (* InspectSsnFunc)(class Flow*);
204 
205 struct InspectApi
206 {
207     BaseApi base;
208     InspectorType type;
209     uint32_t proto_bits;
210 
211     const char** buffers;  // null terminated list of exported buffers
212     const char* service;   // nullptr when type != IT_SERVICE
213 
214     InspectFunc pinit;     // plugin init
215     InspectFunc pterm;     // cleanup pinit()
216     InspectFunc tinit;     // thread local init
217     InspectFunc tterm;     // cleanup tinit()
218     InspectNew ctor;       // instantiate inspector from Module data
219     InspectDelFunc dtor;   // release inspector instance
220     InspectSsnFunc ssn;    // get new session tracker
221     InspectFunc reset;     // clear stats
222 
223     static const char* get_type(InspectorType type);
224 };
225 
get_name()226 inline const char* Inspector::get_name() const
227 { return api->base.name; }
228 }
229 
230 #endif
231 
232