1 /* 2 3 Firewall Builder 4 5 Copyright (C) 2001 NetCitadel, LLC 6 7 Author: Vadim Zaliva lord@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 27 #ifndef __FWOBJECTDATABASE_HH_FLAG__ 28 #define __FWOBJECTDATABASE_HH_FLAG__ 29 30 #include "fwbuilder/FWObject.h" 31 #include "fwbuilder/FWException.h" 32 #include "fwbuilder/ThreadTools.h" 33 #include "fwbuilder/XMLTools.h" 34 35 #ifdef _WIN32 36 # include <sys/timeb.h> 37 # include <process.h> 38 #else 39 # include <sys/types.h> 40 # include <unistd.h> 41 #endif 42 43 #include <time.h> // for time_t 44 45 #define DECLARE_CREATE_OBJ_METHOD(classname) \ 46 FWObject* create_##classname(int id=-1); 47 48 #define DECLARE_CREATE_OBJ_CLASS_METHOD(classname) \ 49 classname * create##classname(int id=-1); 50 51 52 namespace libfwbuilder 53 { 54 class Group; 55 56 // forward declarations for specialized create() methods 57 class AddressRange; 58 class AddressTable; 59 class AttachedNetworks; 60 class Cluster; 61 class StateSyncClusterGroup; 62 class FailoverClusterGroup; 63 class ClusterGroupOptions; 64 class CustomService; 65 class DNSName; 66 class DynamicGroup; 67 class FWBDManagement; 68 class FWIntervalReference; 69 class FWObjectReference; 70 class FWServiceReference; 71 class Firewall; 72 class FirewallOptions; 73 class Host; 74 class HostOptions; 75 class ICMP6Service; 76 class ICMPService; 77 class IPService; 78 class IPv4; 79 class IPv6; 80 class Interface; 81 class InterfaceOptions; 82 class Interval; 83 class IntervalGroup; 84 class Library; 85 class Management; 86 class NAT; 87 class NATRule; 88 class NATRuleOptions; 89 class Network; 90 class NetworkIPv6; 91 class ObjectGroup; 92 class Policy; 93 class PolicyInstallScript; 94 class PolicyRule; 95 class PolicyRuleOptions; 96 class Routing; 97 class RoutingRule; 98 class RoutingRuleOptions; 99 class RuleElementDst; 100 class RuleElementInterval; 101 class RuleElementItf; 102 class RuleElementItfInb; 103 class RuleElementItfOutb; 104 class RuleElementODst; 105 class RuleElementOSrc; 106 class RuleElementOSrv; 107 class RuleElementRDst; 108 class RuleElementRGtw; 109 class RuleElementRItf; 110 class RuleElementSrc; 111 class RuleElementSrv; 112 class RuleElementTDst; 113 class RuleElementTSrc; 114 class RuleElementTSrv; 115 class RuleSetOptions; 116 class SNMPManagement; 117 class ServiceGroup; 118 class TCPService; 119 class TagService; 120 class UDPService; 121 class UserService; 122 class physAddress; 123 124 125 126 DECLARE_CREATE_OBJ_METHOD(AddressRange); 127 DECLARE_CREATE_OBJ_METHOD(AddressTable); 128 DECLARE_CREATE_OBJ_METHOD(AttachedNetworks); 129 DECLARE_CREATE_OBJ_METHOD(Cluster); 130 DECLARE_CREATE_OBJ_METHOD(StateSyncClusterGroup); 131 DECLARE_CREATE_OBJ_METHOD(FailoverClusterGroup); 132 DECLARE_CREATE_OBJ_METHOD(ClusterGroupOptions); 133 DECLARE_CREATE_OBJ_METHOD(CustomService); 134 DECLARE_CREATE_OBJ_METHOD(DNSName); 135 DECLARE_CREATE_OBJ_METHOD(DynamicGroup); 136 DECLARE_CREATE_OBJ_METHOD(FWBDManagement); 137 DECLARE_CREATE_OBJ_METHOD(FWIntervalReference); 138 DECLARE_CREATE_OBJ_METHOD(FWObjectReference); 139 DECLARE_CREATE_OBJ_METHOD(FWServiceReference); 140 DECLARE_CREATE_OBJ_METHOD(Firewall); 141 DECLARE_CREATE_OBJ_METHOD(FirewallOptions); 142 DECLARE_CREATE_OBJ_METHOD(Host); 143 DECLARE_CREATE_OBJ_METHOD(HostOptions); 144 DECLARE_CREATE_OBJ_METHOD(ICMP6Service); 145 DECLARE_CREATE_OBJ_METHOD(ICMPService); 146 DECLARE_CREATE_OBJ_METHOD(IPService); 147 DECLARE_CREATE_OBJ_METHOD(IPv4); 148 DECLARE_CREATE_OBJ_METHOD(IPv6); 149 DECLARE_CREATE_OBJ_METHOD(Interface); 150 DECLARE_CREATE_OBJ_METHOD(InterfaceOptions); 151 DECLARE_CREATE_OBJ_METHOD(Interval); 152 DECLARE_CREATE_OBJ_METHOD(IntervalGroup); 153 DECLARE_CREATE_OBJ_METHOD(Library); 154 DECLARE_CREATE_OBJ_METHOD(Management); 155 DECLARE_CREATE_OBJ_METHOD(NAT); 156 DECLARE_CREATE_OBJ_METHOD(NATRule); 157 DECLARE_CREATE_OBJ_METHOD(NATRuleOptions); 158 DECLARE_CREATE_OBJ_METHOD(Network); 159 DECLARE_CREATE_OBJ_METHOD(NetworkIPv6); 160 DECLARE_CREATE_OBJ_METHOD(ObjectGroup); 161 DECLARE_CREATE_OBJ_METHOD(Policy); 162 DECLARE_CREATE_OBJ_METHOD(PolicyInstallScript); 163 DECLARE_CREATE_OBJ_METHOD(PolicyRule); 164 DECLARE_CREATE_OBJ_METHOD(PolicyRuleOptions); 165 DECLARE_CREATE_OBJ_METHOD(Routing); 166 DECLARE_CREATE_OBJ_METHOD(RoutingRule); 167 DECLARE_CREATE_OBJ_METHOD(RoutingRuleOptions); 168 DECLARE_CREATE_OBJ_METHOD(RuleElementDst); 169 DECLARE_CREATE_OBJ_METHOD(RuleElementInterval); 170 DECLARE_CREATE_OBJ_METHOD(RuleElementItf); 171 DECLARE_CREATE_OBJ_METHOD(RuleElementItfInb); 172 DECLARE_CREATE_OBJ_METHOD(RuleElementItfOutb); 173 DECLARE_CREATE_OBJ_METHOD(RuleElementODst); 174 DECLARE_CREATE_OBJ_METHOD(RuleElementOSrc); 175 DECLARE_CREATE_OBJ_METHOD(RuleElementOSrv); 176 DECLARE_CREATE_OBJ_METHOD(RuleElementRDst); 177 DECLARE_CREATE_OBJ_METHOD(RuleElementRGtw); 178 DECLARE_CREATE_OBJ_METHOD(RuleElementRItf); 179 DECLARE_CREATE_OBJ_METHOD(RuleElementSrc); 180 DECLARE_CREATE_OBJ_METHOD(RuleElementSrv); 181 DECLARE_CREATE_OBJ_METHOD(RuleElementTDst); 182 DECLARE_CREATE_OBJ_METHOD(RuleElementTSrc); 183 DECLARE_CREATE_OBJ_METHOD(RuleElementTSrv); 184 DECLARE_CREATE_OBJ_METHOD(RuleSetOptions); 185 DECLARE_CREATE_OBJ_METHOD(SNMPManagement); 186 DECLARE_CREATE_OBJ_METHOD(ServiceGroup); 187 DECLARE_CREATE_OBJ_METHOD(TCPService); 188 DECLARE_CREATE_OBJ_METHOD(TagService); 189 DECLARE_CREATE_OBJ_METHOD(UDPService); 190 DECLARE_CREATE_OBJ_METHOD(UserService); 191 DECLARE_CREATE_OBJ_METHOD(physAddress); 192 DECLARE_CREATE_OBJ_METHOD(Group); 193 194 195 class IDcounter { 196 197 protected: 198 long cntr; 199 200 public: 201 IDcounter(); get()202 long get() { ++cntr; return cntr; } 203 }; 204 205 class FWObjectDatabase; 206 typedef FWObject*(*create_function_ptr)(int); 207 208 /** 209 * Database of objects. 210 */ 211 class FWObjectDatabase : public FWObject 212 { 213 214 private: 215 void _clearReferenceCounters(FWObject *o); 216 void _fixReferenceCounters(FWObject *o); 217 bool _isInIgnoreList(FWObject *o); 218 219 /* bool _findWhereUsed( */ 220 /* libfwbuilder::FWObject *o, */ 221 /* libfwbuilder::FWObject *p, */ 222 /* std::set<libfwbuilder::FWObject *> &resset); */ 223 224 bool _findWhereObjectIsUsed(libfwbuilder::FWObject *o, 225 libfwbuilder::FWObject *p, 226 std::set<libfwbuilder::FWObject *> &resset, 227 int search_id); 228 229 void _findObjectsInGroup( 230 libfwbuilder::Group *g, 231 std::set<libfwbuilder::FWObject *> &res); 232 Firewall* _findFirewallByNameRecursive( 233 FWObject* db, const std::string &name) throw(FWException); 234 FWObject* _recursively_copy_subtree(FWObject *target, 235 FWObject *source, 236 std::map<int,int> &id_map, 237 const std::string &dedup_attribute); 238 void _copy_foreign_obj_aux(FWObject *target, FWObject *source, 239 std::map<int,int> &id_map, 240 const std::string &dedup_attribute); 241 242 void _setPredictableStrIdsRecursively(FWObject *obj); 243 void _updateNonStandardObjectReferencesRecursively(FWObject *obj); 244 245 protected: 246 247 static const std::string DTD_FILE_NAME ; 248 249 time_t lastModified; 250 int index_hits; 251 int index_misses; 252 std::string data_file; 253 std::map<int, FWObject*> obj_index; 254 int searchId; 255 int predictable_id_tracker; 256 bool ignore_read_only; 257 258 void init_create_methods_table(); 259 void init_id_dict(); 260 261 public: 262 263 DECLARE_FWOBJECT_SUBTYPE(FWObjectDatabase); 264 265 DECLARE_DISPATCH_METHODS(FWObjectDatabase); 266 267 enum {ROOT_ID = 0, 268 ANY_ADDRESS_ID = 1, 269 ANY_SERVICE_ID = 2, 270 ANY_INTERVAL_ID = 3, 271 STANDARD_LIB_ID = 4, 272 USER_LIB_ID = 5, 273 TEMPLATE_LIB_ID = 6, 274 DELETED_OBJECTS_ID = 7, 275 DUMMY_ADDRESS_ID = 8, 276 DUMMY_SERVICE_ID = 9, 277 DUMMY_INTERFACE_ID = 10 278 } standard_ids; 279 280 static void registerObjectType(const std::string &type_name, 281 create_function_ptr create_function); 282 283 /** 284 * this constructor initializes singleton db 285 */ 286 FWObjectDatabase(); 287 /** 288 * this constructor makes a copy of entire tree and does not 289 * intitialize db 290 */ 291 FWObjectDatabase(FWObjectDatabase& d); 292 293 virtual ~FWObjectDatabase(); 294 295 // --- methods dealing with object index 296 297 void addToIndexRecursive(FWObject *o); 298 299 /** 300 * add an object to the index 301 */ 302 void addToIndex(FWObject* obj); 303 304 /** 305 * remove an object from the index 306 */ 307 void removeFromIndex(int id); 308 309 /** 310 * check if an object is present in the index using its ID 311 */ 312 FWObject* checkIndex(int id); 313 314 /** 315 * find an object in the index using its ID 316 */ 317 FWObject* findInIndex(int id); 318 319 /** 320 * build index 321 */ 322 void buildIndex(); 323 324 /** 325 * clear the index 326 */ 327 void clearIndex(); 328 329 /** 330 * this is just like buildIndex, except it also fixes reference 331 * counters in objects. Call this method after loading database 332 * from XML file. This method uses private _fixReferenceCounters 333 */ 334 void reIndex(); 335 336 /** 337 * return index usage statistics 338 */ 339 void getIndexStats(int &index_size, int &hit_counter, int &miss_counter); 340 341 /** 342 * this function is intended for debugging. 343 */ 344 void validateIndex(); 345 346 /** 347 * Some operations, such as object tree merging, should ignore 348 * read-only flag on individual objects. 349 */ getIgnoreReadOnlyFlag()350 bool getIgnoreReadOnlyFlag() { return ignore_read_only; } setIgnoreReadOnlyFlag(bool f)351 void setIgnoreReadOnlyFlag(bool f) { ignore_read_only = f; } 352 353 // --- XML import/export --- 354 355 virtual void fromXML(xmlNodePtr xml_parent_node) throw(FWException); 356 virtual xmlNodePtr toXML(xmlNodePtr parent) throw(FWException); 357 getTimeLastModified()358 time_t getTimeLastModified() { return lastModified; } resetTimeLastModified(time_t t)359 void resetTimeLastModified(time_t t) { lastModified=t; } 360 361 // --- Load/Save --- 362 363 virtual void saveFile(const std::string &filename) throw(FWException); 364 virtual void saveToBuffer(xmlChar **buffer,int *size) throw(FWException); 365 virtual void load( const std::string &filename, 366 XMLTools::UpgradePredicate *upgrade, 367 const std::string &template_dir) throw(FWException); 368 virtual void setDirty(bool f); 369 370 Firewall* findFirewallByName(const std::string &name) throw(FWException); 371 372 FWObjectDatabase* exportSubtree( FWObject *lib ); 373 FWObjectDatabase* exportSubtree( const std::list<FWObject*> &libs ); 374 375 376 /* void findWhereUsed( */ 377 /* libfwbuilder::FWObject *o, */ 378 /* libfwbuilder::FWObject *p, */ 379 /* std::set<libfwbuilder::FWObject *> &resset); */ 380 381 /** 382 * Find reference to object <o> in the subtree rooted at <p>. Do 383 * not search for indirect usage, i.e. when an object has a 384 * reference to a group that in turn has reference to <o>. Search 385 * also includes references to objects used in rule actions Tag 386 * and Branch. 387 */ 388 void findWhereObjectIsUsed( 389 libfwbuilder::FWObject *o, 390 libfwbuilder::FWObject *p, 391 std::set<libfwbuilder::FWObject *> &resset); 392 393 /** 394 * find all objects used by the group 'gr'. Resolve references 395 * recursively (that is, if a group member is another group, this 396 * method descends into it and scans all objects that group uses) 397 */ 398 void findObjectsInGroup( 399 libfwbuilder::Group *g, 400 std::set<libfwbuilder::FWObject *> &resset); 401 402 /** 403 * We ignore read-only flag on individual objects when whole object 404 * tree is duplicated 405 */ 406 virtual FWObject& duplicate(const FWObject *obj, 407 bool preserve_id = true) throw(FWException); 408 409 410 void recursivelyRemoveObjFromTree(FWObject* obj, bool remove_ref=false); 411 412 /** 413 * Copy <source> object and all its children, recursively, into <this> 414 * object tree starting from <target>. <target> is a parent of the copy 415 * of <source> that will be created. 416 * Store ID mapping in <id_map> (as a dictionary old_id -> new_id) 417 */ 418 FWObject* recursivelyCopySubtree(FWObject *target, 419 FWObject *source, 420 std::map<int,int> &id_map); 421 422 /** 423 * Create groups to reproduce path inside given library. If groups 424 * with required names exist, do nothing. Return pointer to the 425 * last object created to copy the path. Do not copy <source> object. 426 * This means returned object can be a parent for the copy of <source>. 427 */ 428 FWObject* reproduceRelativePath(FWObject *lib, const FWObject *source); 429 430 /** 431 * fix references in children of obj according to the map_ids which 432 * maps old IDs to the new ones. Return the number of fixed references. 433 */ 434 int fixReferences(FWObject *obj, const std::map<int,int> &map_ids); 435 436 /** 437 * this predicate is used to hand control over to user in case 438 * when a conflict is detected while merging trees. By default the 439 * old object is overwritten with new one. 440 */ 441 class ConflictResolutionPredicate 442 { 443 public: ~ConflictResolutionPredicate()444 virtual ~ConflictResolutionPredicate() {} askUser(FWObject *,FWObject *)445 virtual bool askUser(FWObject*,FWObject*) 446 { 447 return true; 448 } 449 }; 450 451 void merge(FWObjectDatabase *ndb, ConflictResolutionPredicate *mp=NULL); 452 void findDuplicateIds(FWObjectDatabase *ndb, std::set<int> &dupids); 453 454 void setFileName(const std::string &filename); 455 const std::string& getFileName (); 456 const std::string getFileDir (); 457 458 static int generateUniqueId(); 459 static int registerStringId(const std::string &s_id); 460 static int getIntId(const std::string &s_id); 461 static std::string getStringId(int i_id); 462 463 /** 464 * generate predictable ID based on given prefix by adding sequential 465 * suffix to it. 466 */ 467 std::string getPredictableId(const std::string &prefix); 468 469 /** 470 * This method replaces random string object ids with 471 * predictable ones. This does not change their int IDs, only 472 * string IDs that appear in the XML file when objects are 473 * saved change. 474 * 475 * Used in unit testing to create .fwb files that can be 476 * compared. 477 */ 478 virtual void setPredictableIds(); 479 480 /** 481 * This is the main "Create" method: 482 * it creates instance of FWObject of given type 483 * 484 * if parameter 'create_with_root' is true, this method will create 485 * objects using constructor that uses pointer to this as a parameter, 486 * otherwise empty constructor is used 487 */ 488 FWObject *create(const std::string &type, int id=-1, bool init=true); 489 490 /** 491 * Creates instance of FWObject using its XML representation 492 */ 493 virtual FWObject *createFromXML(xmlNodePtr data); 494 495 /** 496 * Specialized createClass() methods: class name is part of the method 497 * name, e.g. createLibrary(), also these return a pointer to the 498 * corresponding class. Note that each macro declares two methods: 499 * Class* createClass(int,bool) and FWObject* createFWObjectClass(int,bool) 500 */ 501 502 DECLARE_CREATE_OBJ_CLASS_METHOD(AddressRange); 503 DECLARE_CREATE_OBJ_CLASS_METHOD(AddressTable); 504 DECLARE_CREATE_OBJ_CLASS_METHOD(AttachedNetworks); 505 DECLARE_CREATE_OBJ_CLASS_METHOD(Cluster); 506 DECLARE_CREATE_OBJ_CLASS_METHOD(StateSyncClusterGroup); 507 DECLARE_CREATE_OBJ_CLASS_METHOD(FailoverClusterGroup); 508 DECLARE_CREATE_OBJ_CLASS_METHOD(ClusterGroupOptions); 509 DECLARE_CREATE_OBJ_CLASS_METHOD(CustomService); 510 DECLARE_CREATE_OBJ_CLASS_METHOD(DNSName); 511 DECLARE_CREATE_OBJ_CLASS_METHOD(DynamicGroup); 512 DECLARE_CREATE_OBJ_CLASS_METHOD(FWBDManagement); 513 DECLARE_CREATE_OBJ_CLASS_METHOD(FWIntervalReference); 514 DECLARE_CREATE_OBJ_CLASS_METHOD(FWObjectReference); 515 DECLARE_CREATE_OBJ_CLASS_METHOD(FWServiceReference); 516 DECLARE_CREATE_OBJ_CLASS_METHOD(Firewall); 517 DECLARE_CREATE_OBJ_CLASS_METHOD(FirewallOptions); 518 DECLARE_CREATE_OBJ_CLASS_METHOD(Host); 519 DECLARE_CREATE_OBJ_CLASS_METHOD(HostOptions); 520 DECLARE_CREATE_OBJ_CLASS_METHOD(ICMP6Service); 521 DECLARE_CREATE_OBJ_CLASS_METHOD(ICMPService); 522 DECLARE_CREATE_OBJ_CLASS_METHOD(IPService); 523 DECLARE_CREATE_OBJ_CLASS_METHOD(IPv4); 524 DECLARE_CREATE_OBJ_CLASS_METHOD(IPv6); 525 DECLARE_CREATE_OBJ_CLASS_METHOD(Interface); 526 DECLARE_CREATE_OBJ_CLASS_METHOD(InterfaceOptions); 527 DECLARE_CREATE_OBJ_CLASS_METHOD(Interval); 528 DECLARE_CREATE_OBJ_CLASS_METHOD(IntervalGroup); 529 DECLARE_CREATE_OBJ_CLASS_METHOD(Library); 530 DECLARE_CREATE_OBJ_CLASS_METHOD(Management); 531 DECLARE_CREATE_OBJ_CLASS_METHOD(NAT); 532 DECLARE_CREATE_OBJ_CLASS_METHOD(NATRule); 533 DECLARE_CREATE_OBJ_CLASS_METHOD(NATRuleOptions); 534 DECLARE_CREATE_OBJ_CLASS_METHOD(Network); 535 DECLARE_CREATE_OBJ_CLASS_METHOD(NetworkIPv6); 536 DECLARE_CREATE_OBJ_CLASS_METHOD(ObjectGroup); 537 DECLARE_CREATE_OBJ_CLASS_METHOD(Policy); 538 DECLARE_CREATE_OBJ_CLASS_METHOD(PolicyInstallScript); 539 DECLARE_CREATE_OBJ_CLASS_METHOD(PolicyRule); 540 DECLARE_CREATE_OBJ_CLASS_METHOD(PolicyRuleOptions); 541 DECLARE_CREATE_OBJ_CLASS_METHOD(Routing); 542 DECLARE_CREATE_OBJ_CLASS_METHOD(RoutingRule); 543 DECLARE_CREATE_OBJ_CLASS_METHOD(RoutingRuleOptions); 544 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementDst); 545 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementInterval); 546 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementItf); 547 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementItfInb); 548 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementItfOutb); 549 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementODst); 550 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementOSrc); 551 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementOSrv); 552 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementRDst); 553 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementRGtw); 554 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementRItf); 555 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementSrc); 556 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementSrv); 557 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementTDst); 558 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementTSrc); 559 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleElementTSrv); 560 DECLARE_CREATE_OBJ_CLASS_METHOD(RuleSetOptions); 561 DECLARE_CREATE_OBJ_CLASS_METHOD(SNMPManagement); 562 DECLARE_CREATE_OBJ_CLASS_METHOD(ServiceGroup); 563 DECLARE_CREATE_OBJ_CLASS_METHOD(TCPService); 564 DECLARE_CREATE_OBJ_CLASS_METHOD(TagService); 565 DECLARE_CREATE_OBJ_CLASS_METHOD(UDPService); 566 DECLARE_CREATE_OBJ_CLASS_METHOD(UserService); 567 DECLARE_CREATE_OBJ_CLASS_METHOD(physAddress); 568 DECLARE_CREATE_OBJ_CLASS_METHOD(Group); 569 570 571 }; 572 573 } 574 575 #endif 576 577