1 /* 2 3 Firewall Builder 4 5 Copyright (C) 2007 NetCitadel, LLC 6 7 Author: Vadim Kurland vadim@fwbuilder.org 8 9 This program is free software which we release under the GNU General Public 10 License. You may redistribute and/or modify this program under the terms 11 of that license as published by the Free Software Foundation; either 12 version 2 of the License, or (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 To get a copy of the GNU General Public License, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 */ 23 24 25 #ifndef _FWB_POLICY_IMPORTER_H_ 26 #define _FWB_POLICY_IMPORTER_H_ 27 28 #include "fwbuilder/Firewall.h" 29 #include "fwbuilder/Interface.h" 30 #include "fwbuilder/Rule.h" 31 #include "fwbuilder/RuleSet.h" 32 #include "fwbuilder/Logger.h" 33 34 #include "objectMaker.h" 35 #include "addressObjectMaker.h" 36 #include "serviceObjectMaker.h" 37 38 #include <map> 39 #include <list> 40 #include <string> 41 #include <functional> 42 #include <sstream> 43 44 #include <QString> 45 46 typedef std::pair<std::string,std::string> str_tuple; 47 typedef std::vector<std::string> str_vector; 48 49 50 class Importer; 51 52 /* 53 * Used for platforms where interface and direction are set for the 54 * whole ruleset (like in router access lists), as opposed to 55 * platforms where interface and direction are set on a per-rule basis 56 * (iptables) 57 */ 58 59 60 class UnidirectionalRuleSet 61 { 62 63 public: 64 libfwbuilder::RuleSet* ruleset; 65 std::string name; 66 // interface names and directions 67 std::map<std::string,std::string> intf_dir; 68 libfwbuilder::PolicyRule::Action default_action; 69 int created_from_line_number; 70 int default_action_line_number; 71 bool to_be_deleted; 72 UnidirectionalRuleSet()73 UnidirectionalRuleSet() 74 { 75 created_from_line_number = -1; 76 default_action_line_number = -1; 77 default_action = libfwbuilder::PolicyRule::Deny; 78 to_be_deleted = false; 79 } 80 }; 81 82 class ImporterException : public std::exception 83 { 84 QString err; 85 public: ImporterException(const std::string & e)86 ImporterException(const std::string &e) { err = e.c_str(); } ImporterException(const QString & e)87 ImporterException(const QString &e) { err = e; } ~ImporterException()88 virtual ~ImporterException() throw() {} toString()89 QString toString() { return err; } what()90 virtual const char* what() const throw() { return err.toStdString().c_str(); } 91 }; 92 93 class Importer 94 { 95 96 // firewall object 97 // one instance of Importer creates only one firewall object. 98 // 99 // Do not access this member directly, always use getFirewallObject() 100 // This ensures the object is created only when it is needed 101 // so that if we get ane xception in parser early, we do not 102 // create unnecessary object 103 104 libfwbuilder::Firewall *fw; 105 std::string fwname; 106 107 protected: 108 109 AddressObjectMaker *address_maker; 110 ServiceObjectMaker *service_maker; 111 112 int error_counter; 113 114 // line number in the original stream being imported 115 int current_line_number; 116 117 libfwbuilder::FWObject *library; 118 119 std::string input_file_name; 120 std::istringstream &input; 121 122 std::string platform; 123 124 std::string discovered_platform; 125 std::string discovered_version; 126 127 std::string user_choice_host_os; 128 std::string user_choice_version; 129 130 libfwbuilder::Interface* current_interface; 131 132 // map : ruleset name : ruleset 133 // in case of IOS ACls or PIX policy ruleset name == acl name 134 // all other platforms have single ruleset for policy 135 // and another for NAT 136 std::map<const std::string,UnidirectionalRuleSet*> all_rulesets; 137 138 // map : interface name : interface 139 std::map<const std::string,libfwbuilder::Interface*> all_interfaces; 140 141 // map : object signature : object 142 // use this to quickly find objects to avoid creating duplicates 143 std::map<const std::string,libfwbuilder::FWObject*> all_objects; 144 145 // registry of broken objects. Sometimes we create an AddressTable 146 // or a group object during import that may have some kind of a problem 147 // that we leave for the user to fix manually. In order to be able to mark 148 // all rules that use this object as "broken", we should register these 149 // broken objects somewhere. 150 std::map<libfwbuilder::FWObject*, QString> broken_objects; 151 152 UnidirectionalRuleSet* current_ruleset; 153 154 libfwbuilder::Rule* current_rule; 155 156 void addAddressObjectToInterface(libfwbuilder::Interface*intf, 157 const std::string &addr, 158 const std::string &netm); 159 std::string getBadRuleColor(); 160 161 // this method returns fw. It is created if fw==NULL 162 // Using getFirewallObject() instead of accessing fw directly 163 // provides a way to create firewall object only when 164 // it is really needed. 165 libfwbuilder::Firewall* getFirewallObject(); 166 167 168 // need to be able to tell if firewall object has really 169 // been created during import. If the file is empty or in case of 170 // a parser error firewall object may not have been created. 171 // However in other cases there could have been an error after 172 // the object was created. This method allows us to tell one 173 // situation from another. haveFirewallObject()174 bool haveFirewallObject() { return (fw!=NULL); } 175 176 // checks if ruleset "rsname" exists. Returns pointer if yes, 177 // otherwise returns NULL 178 virtual UnidirectionalRuleSet* checkUnidirRuleSet(const std::string &rsname); 179 180 // finds and rturns pointer to ruleset "rsname". If it does not 181 // exists, it is created 182 virtual UnidirectionalRuleSet* getUnidirRuleSet( 183 const std::string &ruleset_name, const std::string &ruleset_type_name); 184 185 virtual libfwbuilder::FWObject* createTCPService(const QString &name=""); 186 virtual libfwbuilder::FWObject* createUDPService(const QString &name=""); 187 188 // create libfwbuilder::ObjectGroup and place all interfaces in it 189 // argument represents a list of interface names 190 virtual libfwbuilder::FWObject* createGroupOfInterfaces( 191 const std::string &ruleset_name, std::list<std::string> &interfaces); 192 193 virtual libfwbuilder::FWObject* makeAddressObj(const std::string addr, 194 const std::string netm); 195 196 virtual libfwbuilder::FWObject* makeSrcObj(); 197 virtual libfwbuilder::FWObject* makeDstObj(); 198 virtual libfwbuilder::FWObject* makeSrvObj(); 199 200 // importer may need to create multiple objects for 201 // either rule element for some platforms. It is more convenient to 202 // make these special virtual methods rather than use createAddress 203 // and createService every time. 204 virtual void addSrc(); 205 virtual void addDst(); 206 virtual void addSrv(); 207 208 virtual void addOSrc(); 209 virtual void addODst(); 210 virtual void addOSrv(); 211 212 virtual void addLogging(); 213 214 void registerBrokenObject(libfwbuilder::FWObject *o, const QString &err); 215 bool isObjectBroken(libfwbuilder::FWObject*); 216 QString getBrokenObjectError(libfwbuilder::FWObject*); 217 218 public: 219 220 ObjectMakerErrorTracker *error_tracker; 221 222 // making logger public so I can access it from the code in the grammar 223 libfwbuilder::Logger *logger; 224 225 QStringList last_comment; 226 bool add_standard_comments; 227 228 // temporary variables used by parser to store values 229 // Importer converts these into a proper rule using method 230 // pushRule() 231 // Method clear() resets all these variables to their defaults. 232 // 233 // TODO: need to add more variables to cover everything needed 234 // for NAT rules 235 236 std::string action; 237 std::string protocol; 238 std::string rule_comment; 239 240 std::string src_a; 241 std::string src_nm; 242 std::string src_port_op; 243 std::string src_port_spec; 244 245 std::string dst_a; 246 std::string dst_nm; 247 std::string dst_port_op; 248 std::string dst_port_spec; 249 250 std::string tmp_a; 251 std::string tmp_nm; 252 std::string tmp_port_op; 253 std::string tmp_port_spec; 254 std::string tmp_port_spec_2; 255 256 std::string tmp_range_1; 257 std::string tmp_range_2; 258 259 int tmp_tcp_flag_code; 260 QList<int> tmp_tcp_flags_list; 261 QList<int> tcp_flags_mask; 262 QList<int> tcp_flags_comp; 263 264 bool logging; 265 std::string log_level; 266 std::string log_interval; 267 268 bool established; 269 bool fragments; 270 271 std::string icmp_spec; 272 std::string icmp_code; 273 std::string icmp_type; 274 275 std::string time_range_name; 276 277 void SaveTmpAddrToSrc(); 278 void SaveTmpAddrToDst(); 279 280 void SaveTmpPortToSrc(); 281 void SaveTmpPortToDst(); 282 283 void setSrcSelf(); 284 void setDstSelf(); 285 286 virtual void clear(); 287 288 Importer(libfwbuilder::FWObject *lib, 289 const std::string &platform, 290 std::istringstream &input, 291 libfwbuilder::Logger *log, 292 const std::string &fwname); 293 virtual ~Importer(); 294 295 virtual void run(); 296 setFileName(const std::string & fn)297 void setFileName(const std::string &fn) { input_file_name = fn; } setPlatform(const std::string & pl)298 void setPlatform(const std::string &pl) { platform = pl; } 299 void prepareForDeduplication(); 300 301 // add standard line to rule comment, this adds something like 302 // "created during import from <file>, line <line>" 303 virtual void addStandardImportComment(libfwbuilder::FWObject *obj, 304 const QString &additional_comment); 305 306 virtual libfwbuilder::FWObject* commitObject(libfwbuilder::FWObject *obj); 307 errorCounter()308 int errorCounter() { return error_counter; } 309 310 virtual void setDiscoveredPlatform(const std::string &v); 311 virtual void setDiscoveredVersion(const std::string &v); 312 setUserChoiceHostOS(const std::string & s)313 void setUserChoiceHostOS(const std::string &s) { user_choice_host_os = s; } setUserChoiceVersion(const std::string & s)314 void setUserChoiceVersion(const std::string &s) { user_choice_version = s; } setAddStandardCommentsFlag(bool f)315 void setAddStandardCommentsFlag(bool f) { add_standard_comments = f; } 316 317 virtual void setHostName(const std::string &hn); 318 virtual libfwbuilder::Interface* newInterface(const std::string &interface_name); clearCurrentInterface()319 virtual void clearCurrentInterface() { current_interface = NULL; } 320 virtual void ignoreCurrentInterface(); 321 virtual void addInterfaceAddress(const std::string &a, 322 const std::string &nm); 323 virtual void addInterfaceAddress(const std::string &label, 324 const std::string &a, 325 const std::string &nm); 326 virtual void setInterfaceComment(const std::string &descr); 327 virtual void setInterfaceLabel(const std::string &descr); 328 virtual void setInterfaceSecurityLevel(const std::string &seclevel); 329 virtual void setInterfaceParametes(const std::string &phys_intf, 330 const std::string &label, 331 const std::string &sec_level); 332 virtual void setInterfaceVlanId(const std::string &vlan_id); 333 334 virtual void addRuleComment(const std::string &comm); 335 336 /** 337 * create new unidirectional ruleset. Unidirectional ruleset 338 * has interface association and direction that apply to all rules 339 * in the set. 340 */ 341 virtual void newUnidirRuleSet(const std::string &name, 342 const std::string &ruleset_type); 343 344 /** 345 * Sets default action for the current rule set. 346 */ 347 virtual void setDefaultAction(const std::string &iptables_action_name); 348 349 /** 350 * add interface and direction setting to a ruleset. Note that the 351 * same ruleset may be associated with multiple interfaces and 352 * each association may have its own direction. 353 */ 354 virtual void setInterfaceAndDirectionForRuleSet( 355 const std::string &ruleset_name, 356 const std::string &interface_name, 357 const std::string &dir); 358 359 virtual void setInterfaceAndDirectionForRuleSet( 360 libfwbuilder::Interface *intf, 361 const std::string &ruleset_name, 362 const std::string &dir); 363 364 virtual void newPolicyRule(); 365 virtual void newNATRule(); 366 virtual void pushRule(); 367 setCurrentLineNumber(int n)368 void setCurrentLineNumber(int n) { current_line_number = n; } getCurrentLineNumber()369 int getCurrentLineNumber() { return current_line_number;} 370 371 void markCurrentRuleBad(); 372 void reportError(const std::string &comment); 373 void reportError(const QString &comment); 374 375 // this method actually adds interfaces to the firewall object 376 // and does final clean up. 377 virtual libfwbuilder::Firewall* finalize(); 378 379 int countRules(); 380 int countInterfaces(); 381 382 QString noFirewallErrorMessage(); 383 QString noRulesErrorMessage(); 384 QString noInterfacesErrorMessage(); 385 QString commonFailureErrorMessage(); 386 387 // statistics 388 int getNumberOfRuleSets(); 389 int getTotalNumberOfRules(); 390 int getNumberOfInterfaces(); 391 392 void addMessageToLog(const std::string &msg); 393 void addMessageToLog(const QString &msg); 394 395 396 void rearrangeVlanInterfaces(); 397 398 }; 399 400 #endif 401