1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2007 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@vk.crocodile.org
8 
9   $Id$
10 
11   This program is free software which we release under the GNU General Public
12   License. You may redistribute and/or modify this program under the terms
13   of that license as published by the Free Software Foundation; either
14   version 2 of the License, or (at your option) any later version.
15 
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20 
21   To get a copy of the GNU General Public License, write to the Free Software
22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 
24 */
25 
26 #ifndef __POLICYCOMPILER_NXOSACL_HH
27 #define __POLICYCOMPILER_NXOSACL_HH
28 
29 #include <fwbuilder/libfwbuilder-config.h>
30 
31 #include "fwcompiler/PolicyCompiler.h"
32 #include "fwbuilder/RuleElement.h"
33 #include "fwbuilder/TCPService.h"
34 
35 #include "Helper.h"
36 #include "ACL.h"
37 #include "PolicyCompiler_cisco.h"
38 
39 #include <functional>
40 
41 namespace libfwbuilder {
42     class IPService;
43     class ICMPService;
44     class TCPService;
45     class UDPService;
46     class RuleElementSrc;
47     class RuleElementDst;
48     class RuleElementSrv;
49     class Group;
50 };
51 
52 namespace fwcompiler {
53 
54     class PolicyCompiler_nxosacl : public PolicyCompiler_cisco {
55 
56         protected:
57 
58         std::string comment_symbol;
59 
60         /**
61          * dynamic interfaces can not be used in policy rules in NXOS ACLs
62          */
63         friend class checkForDynamicInterface;
64         class checkForDynamicInterface : public PolicyRuleProcessor
65         {
66             bool findDynamicInterface(libfwbuilder::PolicyRule *rule,
67                                       libfwbuilder::RuleElement *re);
68             public:
checkForDynamicInterface(const std::string & name)69             checkForDynamicInterface(const std::string &name) : PolicyRuleProcessor(name) {}
70             virtual bool processNext();
71         };
72 
73         /*
74          *************************************************************************
75          *
76          * the following rule processors are intended for NXOSACL < 7.0
77          * the code is in the module PolicyCompiler_nxosacl_v6_acls.cpp
78          *
79          *************************************************************************
80          */
81 
82 
83 	/**
84          *   verifies combination of interface and direction and
85          *   fills interface and direction. After this predicate it
86          *   is guaranteed that both interface and direction have
87          *   some value. In certain situations interface ID may be
88          *   set to "nil" though (e.g. global policy rules).
89 	 */
90 	DECLARE_POLICY_RULE_PROCESSOR( InterfaceAndDirection_v6 );
91 
92 	/**
93 	 * if interface has not been defined (this is global policy
94 	 * rule), then multiply the rule for each interface and set
95 	 * direction to "Inbound"
96 	 */
97 	DECLARE_POLICY_RULE_PROCESSOR( assignRuleToInterface_v6 );
98 
99 	/**
100 	 * split rules with direction "both".
101 	 * TODO: This is used in OpenBSD pf. Move to class PolicyCompiler
102 	 */
103 	DECLARE_POLICY_RULE_PROCESSOR( SplitDirection_v6 );
104 
105 	/**
106 	 * in NXOSACL, ACLs are always applied on interface and direction
107 	 * can only be "inbound". We emulate outbound ACLs though.
108 	 */
109 	DECLARE_POLICY_RULE_PROCESSOR( EmulateOutboundACL_v6 );
110 
111 	/**
112 	 * determine acl rules should belong to
113 	 */
114 	DECLARE_POLICY_RULE_PROCESSOR( pickACL_v6   );
115         friend class PolicyCompiler_nxosacl::pickACL_v6;
116 
117         /*
118          *************************************************************************
119          *
120          * end of module PolicyCompiler_nxosacl_v6_acls.cpp
121          *
122          *************************************************************************
123          */
124 
125         /*
126          *************************************************************************
127          *
128          * rule processors intended to manage ACLs for NXOSACL < 7.0 are inherited
129          * from PolicyCompiler_cisco.
130          * The code is in the module PolicyCompiler_cisco_acls.cpp
131          *
132          * The processors assume that all objects in src and dst
133          * belong to the same network zone (respectively)
134          *
135          * All these rule processors assume outbound ACLs are supported.
136          * Check corresponding capability flag and do not include these
137          * processors in the processors chain in nxosacl.cpp if outbound acls
138          * are not supported.
139          *
140          *************************************************************************
141          */
142 
143 	/**
144 	 * this processor checks for the services which require
145 	 * special treatment.  Some of these will be checking for
146 	 * source or destination object as well because special
147 	 * command may need to be generated in case source or
148 	 * destination is a firewall itself. Therefore this processor
149 	 * should be called after converting to atomic rules, but
150 	 * before interface addresses in source and destination are
151 	 * expanded.
152 	 */
153 	DECLARE_POLICY_RULE_PROCESSOR( SpecialServices );
154         friend class PolicyCompiler_nxosacl::SpecialServices;
155 
156 	/**
157 	 * to implement action "Reject" add command "service resetinbound"
158 	 */
159 	DECLARE_POLICY_RULE_PROCESSOR( RejectAction );
160         friend class PolicyCompiler_nxosacl::RejectAction;
161 
162 	/**
163 	 * Implements "mirrored" rules
164 	 */
165         class mirrorRule : public PolicyRuleProcessor
166         {
167             void duplicateRuleElement(libfwbuilder::RuleElement *re1,
168                                       libfwbuilder::RuleElement *re2);
169             public:
mirrorRule(const std::string & n)170             mirrorRule(const std::string &n) : PolicyRuleProcessor(n) {}
171             virtual bool processNext();
172         };
173         friend class PolicyCompiler_nxosacl::mirrorRule;
174 
175 	/**
176 	 * this processor accumulates all rules fed to it by previous
177 	 * * processors, prints commands to clear access-lists, then
178 	 * feeds all rules to the next processor. Usually this
179 	 * processor is in chain right before PrintRules.
180          *
181          * We use this processor to print "clear" commands because
182          * they need to be generated when all access lists have been
183          * created but before they are printed.
184 	 */
185         class ClearACLs : public PolicyRuleProcessor
186         {
187             public:
ClearACLs(const std::string & n)188             ClearACLs(const std::string &n) : PolicyRuleProcessor(n) {}
189             virtual bool processNext();
190         };
191         friend class PolicyCompiler_nxosacl::ClearACLs;
192 
193         /**
194          * "object-group service" does not seem to support matching of
195          * tcp flags and "established". Need to separate objects using
196          * these into separate rules to avoid object-group
197          */
198         DECLARE_POLICY_RULE_PROCESSOR(splitTCPServiceWithFlags);
199         friend class PolicyCompiler_nxosacl::splitTCPServiceWithFlags;
200 
201 	/**
202 	 *  this processor prints single policy rule, assuming all
203 	 *  groups have been expanded, so source, destination and
204 	 *  service hold exactly one object each, and this object is
205 	 *  not a group.  Negation should also have been taken care of
206 	 *  before this method is called.
207 	 */
208         class PrintRule : public PolicyRuleProcessor
209         {
210             protected:
211             std::string                         current_rule_label1;
212             std::map<std::string,std::string>   current_rule_label2;
213             int                                 aclLineCounter;
214 
215             std::string _printPortRangeOp(int rs, int re);
216 
217             std::string getTcpFlagName(const libfwbuilder::TCPService::TCPFlag f);
218             std::string _printSrcService(libfwbuilder::Service *srv);
219             std::string _printDstService(libfwbuilder::Service *srv);
220             std::string _printAddr(libfwbuilder::Address  *o);
221             std::string _printProtocol(libfwbuilder::Service *srv);
222             std::string _printTCPFlags(libfwbuilder::TCPService *srv);
223             std::string _printAction(libfwbuilder::PolicyRule *r);
224             std::string _printACL(libfwbuilder::PolicyRule *r);
225             std::string _printLog(libfwbuilder::PolicyRule *r);
226             std::string _printIPServiceOptions(libfwbuilder::PolicyRule *r);
227 
228             std::string _printRule(libfwbuilder::PolicyRule *rule);
229 
230             public:
PrintRule(const std::string & name)231             PrintRule(const std::string &name) : PolicyRuleProcessor(name) { aclLineCounter=0; }
232             virtual bool processNext();
233         };
234         friend class PolicyCompiler_nxosacl::PrintRule;
235 
236 	/**
237 	 * this processor accumulates all rules fed to it by previous
238 	 * * processors, prints commands to clear access-lists, then
239 	 * generates commands for the new ACLs.
240          *
241 	 */
242         class PrintCompleteACLs : public PrintRule
243         {
244             public:
PrintCompleteACLs(const std::string & n)245             PrintCompleteACLs(const std::string &n) : PrintRule(n) {}
246             virtual bool processNext();
247 
248             struct printRulesForACL : public std::unary_function<libfwbuilder::Rule*, void>
249             {
250                 ciscoACL *acl;
251                 std::stringstream *output;
252                 PolicyCompiler_nxosacl *nxosacl_comp;
253                 PolicyCompiler_nxosacl::PrintCompleteACLs *print_acl_p;
254 
printRulesForACLprintRulesForACL255                 printRulesForACL(PolicyCompiler_nxosacl *_comp,
256                                  PolicyCompiler_nxosacl::PrintCompleteACLs *pp,
257                                  ciscoACL* _acl,
258                                  std::stringstream *_out)
259                 { nxosacl_comp = _comp; print_acl_p = pp; acl = _acl; output = _out; }
260 
261                 // print rule if it belongs to ACL <acl>
262                 void operator() (libfwbuilder::Rule* x);
263             };
264             friend struct PrintCompleteACLs::printRulesForACL;
265         };
266         friend class PolicyCompiler_nxosacl::PrintCompleteACLs;;
267 
268 
269 	bool resetinbound;
270 	bool fragguard;
271 
272 	protected:
273 
274 	virtual std::string myPlatformName();
275         virtual std::string printAccessGroupCmd(ciscoACL *acl, bool neg=false);
276 
277 	public:
278 
279 	PolicyCompiler_nxosacl(libfwbuilder::FWObjectDatabase *_db,
280                               libfwbuilder::Firewall *fw,
281                               bool ipv6_policy,
282                               fwcompiler::OSConfigurator *_oscnf);
~PolicyCompiler_nxosacl()283         virtual ~PolicyCompiler_nxosacl() {}
284 
285 	virtual int  prolog();
286 	virtual void compile();
287 	virtual void epilog();
288 
289         virtual std::string printClearCommands();
290 
291         static std::string getAccessGroupCommandForAddressFamily(bool ipv6);
292 
293     };
294 
295 
296 }
297 
298 #endif
299