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