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