1 //--------------------------------------------------------------------------
2 // Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 // Copyright (C) 2013-2013 Sourcefire, Inc.
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License Version 2 as published
7 // by the Free Software Foundation. You may not use, modify or distribute
8 // this program under any other version of the GNU General Public License.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 //--------------------------------------------------------------------------
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "policy.h"
25
26 #include "daq_common.h"
27
28 #include "actions/actions.h"
29 #include "detection/detection_engine.h"
30 #include "framework/policy_selector.h"
31 #include "log/messages.h"
32 #include "managers/inspector_manager.h"
33 #include "parser/parse_conf.h"
34 #include "parser/vars.h"
35 #include "ports/port_var_table.h"
36
37 #include "modules.h"
38 #include "shell.h"
39 #include "snort_config.h"
40
41 using namespace snort;
42
43 //-------------------------------------------------------------------------
44 // traffic policy
45 //-------------------------------------------------------------------------
46
NetworkPolicy(PolicyId id,PolicyId default_inspection_id)47 NetworkPolicy::NetworkPolicy(PolicyId id, PolicyId default_inspection_id)
48 : policy_id(id), default_inspection_policy_id(default_inspection_id)
49 { init(nullptr, nullptr); }
50
NetworkPolicy(NetworkPolicy * other_network_policy,const char * exclude_name)51 NetworkPolicy::NetworkPolicy(NetworkPolicy* other_network_policy, const char* exclude_name)
52 { init(other_network_policy, exclude_name); }
53
~NetworkPolicy()54 NetworkPolicy::~NetworkPolicy()
55 { InspectorManager::delete_policy(this, cloned); }
56
init(NetworkPolicy * other_network_policy,const char * exclude_name)57 void NetworkPolicy::init(NetworkPolicy* other_network_policy, const char* exclude_name)
58 {
59 if (other_network_policy)
60 {
61 dbus.clone(other_network_policy->dbus, exclude_name);
62 policy_id = other_network_policy->policy_id;
63 default_inspection_policy_id = other_network_policy->default_inspection_policy_id;
64 user_policy_id = other_network_policy->user_policy_id;
65
66 min_ttl = other_network_policy->min_ttl;
67 new_ttl = other_network_policy->new_ttl;
68
69 checksum_eval = other_network_policy->checksum_eval;
70 checksum_drop = other_network_policy->checksum_drop;
71 normal_mask = other_network_policy->normal_mask;
72 }
73 InspectorManager::new_policy(this, other_network_policy);
74 }
75
76 //-------------------------------------------------------------------------
77 // inspection policy
78 //-------------------------------------------------------------------------
79
80 class AltPktHandler : public DataHandler
81 {
82 public:
AltPktHandler()83 AltPktHandler() : DataHandler("detection") { }
84
handle(DataEvent & e,Flow *)85 void handle(DataEvent& e, Flow*) override
86 { DetectionEngine::detect(const_cast<Packet*>(e.get_packet())); }
87 };
88
InspectionPolicy(PolicyId id)89 InspectionPolicy::InspectionPolicy(PolicyId id)
90 {
91 policy_id = id;
92 init(nullptr);
93 }
94
InspectionPolicy(InspectionPolicy * other_inspection_policy)95 InspectionPolicy::InspectionPolicy(InspectionPolicy* other_inspection_policy)
96 { init(other_inspection_policy); }
97
init(InspectionPolicy * other_inspection_policy)98 void InspectionPolicy::init(InspectionPolicy* other_inspection_policy)
99 {
100 framework_policy = nullptr;
101 cloned = false;
102 if (other_inspection_policy)
103 {
104 policy_id = other_inspection_policy->policy_id;
105 policy_mode = other_inspection_policy->policy_mode;
106 user_policy_id = other_inspection_policy->user_policy_id;
107 #ifdef HAVE_UUID
108 uuid_copy(uuid, other_inspection_policy->uuid);
109 #endif
110 }
111 InspectorManager::new_policy(this, other_inspection_policy);
112 }
113
~InspectionPolicy()114 InspectionPolicy::~InspectionPolicy()
115 {
116 InspectorManager::delete_policy(this, cloned);
117 }
118
configure()119 void InspectionPolicy::configure()
120 {
121 dbus.subscribe(PACKET_EVENT, new AltPktHandler);
122 }
123
124 //-------------------------------------------------------------------------
125 // detection policy
126 //-------------------------------------------------------------------------
127
IpsPolicy(PolicyId id)128 IpsPolicy::IpsPolicy(PolicyId id) : action(Actions::get_max_types(), nullptr)
129 {
130 policy_id = id;
131 user_policy_id = 0;
132 policy_mode = POLICY_MODE__MAX;
133
134 var_table = nullptr;
135
136 var_id = 1;
137 ip_vartable = sfvt_alloc_table();
138 portVarTable = PortVarTableCreate();
139 nonamePortVarTable = PortTableNew();
140
141 enable_builtin_rules = false;
142 obfuscate_pii = false;
143 }
144
~IpsPolicy()145 IpsPolicy::~IpsPolicy()
146 {
147 if ( var_table )
148 DeleteVars(var_table);
149
150 if ( ip_vartable )
151 sfvt_free_table(ip_vartable);
152
153 if ( portVarTable )
154 PortVarTableFree(portVarTable);
155
156 if ( nonamePortVarTable )
157 PortTableFree(nonamePortVarTable);
158 }
159
160 //-------------------------------------------------------------------------
161 // policy map
162 //-------------------------------------------------------------------------
163
PolicyMap(PolicyMap * other_map,const char * exclude_name)164 PolicyMap::PolicyMap(PolicyMap* other_map, const char* exclude_name)
165 {
166 if ( other_map )
167 clone(other_map, exclude_name);
168 else
169 {
170 add_shell(new Shell(nullptr, true), true);
171 empty_ips_policy = new IpsPolicy(ips_policy.size());
172 ips_policy.push_back(empty_ips_policy);
173 }
174
175 set_network_policy(network_policy[0]);
176 set_inspection_policy(inspection_policy[0]);
177 set_ips_policy(ips_policy[0]);
178 }
179
~PolicyMap()180 PolicyMap::~PolicyMap()
181 {
182 if ( cloned )
183 {
184 if ( !inspection_policy.empty() )
185 {
186 InspectionPolicy* default_policy = inspection_policy[0];
187 default_policy->cloned = true;
188 delete default_policy;
189 }
190 if ( !network_policy.empty() )
191 {
192 NetworkPolicy* default_policy = network_policy[0];
193 default_policy->cloned = true;
194 delete default_policy;
195 }
196 }
197 else
198 {
199 for ( auto p : shells )
200 delete p;
201
202 for ( auto p : inspection_policy )
203 delete p;
204
205 for ( auto p : ips_policy )
206 delete p;
207
208 for ( auto p : network_policy )
209 delete p;
210
211 }
212
213 shells.clear();
214 inspection_policy.clear();
215 ips_policy.clear();
216 network_policy.clear();
217 shell_map.clear();
218 }
219
clone(PolicyMap * other_map,const char * exclude_name)220 void PolicyMap::clone(PolicyMap *other_map, const char* exclude_name)
221 {
222 shells = other_map->shells;
223 ips_policy = other_map->ips_policy;
224 empty_ips_policy = other_map->empty_ips_policy;
225
226 for ( unsigned i = 0; i < (other_map->network_policy.size()); i++)
227 {
228 if ( i == 0 )
229 network_policy.emplace_back(new NetworkPolicy(other_map->network_policy[i],
230 exclude_name));
231 else
232 network_policy.emplace_back(other_map->network_policy[i]);
233 }
234
235 for ( unsigned i = 0; i < (other_map->inspection_policy.size()); i++)
236 {
237 if ( i == 0 )
238 inspection_policy.emplace_back(new InspectionPolicy(other_map->inspection_policy[i]));
239 else
240 inspection_policy.emplace_back(other_map->inspection_policy[i]);
241 }
242
243 shell_map = other_map->shell_map;
244 // Fix references to network_policy[0] and inspection_policy[0]
245 for ( auto p : other_map->shell_map )
246 {
247 if ( p.second->network == other_map->network_policy[0] )
248 shell_map[p.first]->network = network_policy[0];
249 if ( p.second->inspection == other_map->inspection_policy[0] )
250 shell_map[p.first] = std::make_shared<PolicyTuple>(inspection_policy[0], p.second->ips,
251 p.second->network);
252 }
253
254 user_network = other_map->user_network;
255 // Fix references to network_policy[0]
256 for ( auto p : other_map->user_network )
257 {
258 if ( p.second == other_map->network_policy[0] )
259 user_network[p.first] = network_policy[0];
260 }
261
262 user_inspection = other_map->user_inspection;
263 // Fix references to inspection_policy[0]
264 for ( auto p : other_map->user_inspection )
265 {
266 if ( p.second == other_map->inspection_policy[0] )
267 user_inspection[p.first] = inspection_policy[0];
268 }
269
270 user_ips = other_map->user_ips;
271 }
272
add_inspection_shell(Shell * sh)273 InspectionPolicy* PolicyMap::add_inspection_shell(Shell* sh)
274 {
275 unsigned idx = inspection_policy.size();
276 InspectionPolicy* p = new InspectionPolicy(idx);
277
278 shells.push_back(sh);
279 inspection_policy.push_back(p);
280 shell_map[sh] = std::make_shared<PolicyTuple>(p, nullptr, nullptr);
281
282 return p;
283 }
284
add_ips_shell(Shell * sh)285 IpsPolicy* PolicyMap::add_ips_shell(Shell* sh)
286 {
287 unsigned idx = ips_policy.size();
288 IpsPolicy* p = new IpsPolicy(idx);
289
290 shells.push_back(sh);
291 ips_policy.push_back(p);
292 shell_map[sh] = std::make_shared<PolicyTuple>(nullptr, p, nullptr);
293
294 return p;
295 }
296
add_shell(Shell * sh,bool include_network)297 std::shared_ptr<PolicyTuple> PolicyMap::add_shell(Shell* sh, bool include_network)
298 {
299 shells.push_back(sh);
300 inspection_policy.push_back(new InspectionPolicy(inspection_policy.size()));
301 InspectionPolicy* ip = inspection_policy.back();
302 NetworkPolicy* new_network_policy = nullptr;
303 if (include_network)
304 {
305 new_network_policy = new NetworkPolicy(network_policy.size(), ip->policy_id);
306 network_policy.push_back(new_network_policy);
307 }
308 ips_policy.push_back(new IpsPolicy(ips_policy.size()));
309 return shell_map[sh] = std::make_shared<PolicyTuple>(ip,
310 ips_policy.back(), new_network_policy);
311 }
312
get_policies(Shell * sh)313 std::shared_ptr<PolicyTuple> PolicyMap::get_policies(Shell* sh)
314 {
315 const auto& pt = shell_map.find(sh);
316
317 return pt == shell_map.end() ? nullptr : pt->second;
318 }
319
320 //-------------------------------------------------------------------------
321 // policy nav
322 //-------------------------------------------------------------------------
323
324 static THREAD_LOCAL NetworkPolicy* s_traffic_policy = nullptr;
325 static THREAD_LOCAL InspectionPolicy* s_inspection_policy = nullptr;
326 static THREAD_LOCAL IpsPolicy* s_detection_policy = nullptr;
327
328 namespace snort
329 {
get_network_policy()330 NetworkPolicy* get_network_policy()
331 { return s_traffic_policy; }
332
get_inspection_policy()333 InspectionPolicy* get_inspection_policy()
334 { return s_inspection_policy; }
335
get_ips_policy()336 IpsPolicy* get_ips_policy()
337 { return s_detection_policy; }
338
set_network_policy(NetworkPolicy * p)339 void set_network_policy(NetworkPolicy* p)
340 { s_traffic_policy = p; }
341
set_inspection_policy(InspectionPolicy * p)342 void set_inspection_policy(InspectionPolicy* p)
343 { s_inspection_policy = p; }
344
set_ips_policy(IpsPolicy * p)345 void set_ips_policy(IpsPolicy* p)
346 { s_detection_policy = p; }
347
get_user_inspection_policy(const SnortConfig * sc,unsigned policy_id)348 InspectionPolicy* get_user_inspection_policy(const SnortConfig* sc, unsigned policy_id)
349 {
350 return sc->policy_map->get_user_inspection(policy_id);
351 }
352
get_default_network_policy(const SnortConfig * sc)353 NetworkPolicy* get_default_network_policy(const SnortConfig* sc)
354 { return sc->policy_map->get_network_policy(0); }
355
get_default_inspection_policy(const SnortConfig * sc)356 InspectionPolicy* get_default_inspection_policy(const SnortConfig* sc)
357 {
358 return
359 sc->policy_map->get_inspection_policy(get_network_policy()->default_inspection_policy_id);
360 }
361
get_ips_policy(const SnortConfig * sc,unsigned i)362 IpsPolicy* get_ips_policy(const SnortConfig* sc, unsigned i)
363 {
364 return sc && i < sc->policy_map->ips_policy_count() ?
365 sc->policy_map->get_ips_policy(i) : nullptr;
366 }
367
get_user_ips_policy(const SnortConfig * sc,unsigned policy_id)368 IpsPolicy* get_user_ips_policy(const SnortConfig* sc, unsigned policy_id)
369 {
370 return sc->policy_map->get_user_ips(policy_id);
371 }
372
get_empty_ips_policy(const SnortConfig * sc)373 IpsPolicy* get_empty_ips_policy(const SnortConfig* sc)
374 {
375 return sc->policy_map->get_empty_ips();
376 }
377 } // namespace snort
378
set_network_policy(const SnortConfig * sc,unsigned i)379 void set_network_policy(const SnortConfig* sc, unsigned i)
380 {
381 PolicyMap* pm = sc->policy_map;
382
383 if ( i < pm->network_policy_count() )
384 set_network_policy(pm->get_network_policy(i));
385 }
386
set_inspection_policy(const SnortConfig * sc,unsigned i)387 void set_inspection_policy(const SnortConfig* sc, unsigned i)
388 {
389 PolicyMap* pm = sc->policy_map;
390
391 if ( i < pm->inspection_policy_count() )
392 set_inspection_policy(pm->get_inspection_policy(i));
393 }
394
set_ips_policy(const SnortConfig * sc,unsigned i)395 void set_ips_policy(const SnortConfig* sc, unsigned i)
396 {
397 PolicyMap* pm = sc->policy_map;
398
399 if ( i < pm->ips_policy_count() )
400 set_ips_policy(pm->get_ips_policy(i));
401 }
402
set_policies(const SnortConfig * sc,Shell * sh)403 void set_policies(const SnortConfig* sc, Shell* sh)
404 {
405 auto policies = sc->policy_map->get_policies(sh);
406
407 if ( policies->inspection )
408 set_inspection_policy(policies->inspection);
409
410 if ( policies->ips )
411 set_ips_policy(policies->ips);
412
413 if ( policies->network )
414 set_network_policy(policies->network);
415 }
416
set_default_policy(const SnortConfig * sc)417 void set_default_policy(const SnortConfig* sc)
418 {
419 set_network_policy(sc->policy_map->get_network_policy(0));
420 set_inspection_policy(sc->policy_map->get_inspection_policy(0));
421 set_ips_policy(sc->policy_map->get_ips_policy(0));
422 }
423
select_default_policy(const _daq_pkt_hdr * pkthdr,const SnortConfig * sc)424 void select_default_policy(const _daq_pkt_hdr* pkthdr, const SnortConfig* sc)
425 {
426 if (!sc->global_selector || !sc->global_selector->select_default_policies(pkthdr, sc))
427 {
428 set_network_policy(sc->policy_map->get_network_policy(0));
429 set_inspection_policy(sc->policy_map->get_inspection_policy(0));
430 set_ips_policy(sc->policy_map->get_ips_policy(0));
431 }
432 }
433
only_inspection_policy()434 bool only_inspection_policy()
435 { return get_inspection_policy() && !get_ips_policy() && !get_network_policy(); }
436
only_ips_policy()437 bool only_ips_policy()
438 { return get_ips_policy() && !get_inspection_policy() && !get_network_policy(); }
439
440