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