/* * This is identical to * PolicyCompiler_ipf::processMultiAddressObjectsInRE::processNext() * TODO: move the code to the class Compiler so it can be reused. */ bool RoutingCompiler::processMultiAddressObjectsInRE::processNext() { RoutingRule *rule = getNext(); if (rule==NULL) return false; RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) ); for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) compiler->abort( rule, "Run-time AddressTable objects are not supported."); AddressTable *at = AddressTable::cast(o); if (at && at->isRunTime()) compiler->abort( rule, "Run-time AddressTable objects are not supported."); } tmp_queue.push_back(rule); return true; }
void NATCompiler_ipf::PrintRule::_printAddr_L(Address *o, bool print_netmask) { FWOptions* options=compiler->fw->getOptionsObject(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=nullptr) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } // at this time we only support two types of MultiAddress // objects: AddressTable and DNSName. Both should be converted // to MultiAddressRunTime at this point. If we get some other // kind of MultiAddressRunTime object, we do not know what to do // with it so we stop. assert(atrt==nullptr); } if (Interface::cast(o)!=nullptr && Interface::cast(o)->isDyn()) { if (options->getBool("dynAddr")) compiler->output << "(" << o->getName() << ") "; else compiler->output << "any "; return; } const InetAddr *addr = o->getAddressPtr(); if (addr) { InetAddr mask = *(o->getNetmaskPtr()); if (Interface::cast(o)!=nullptr && ! Interface::cast(o)->isDyn()) mask = InetAddr(InetAddr::getAllOnes()); if (o->dimension()==1) mask = InetAddr(InetAddr::getAllOnes()); if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { compiler->output << addr->toString(); if (print_netmask) compiler->output << "/" << mask.getLength(); compiler->output << " "; } } }
void* ObjectMatcher::dispatch(Firewall *obj1, void *_obj2) { FWObject *obj2 = (FWObject*)(_obj2); if (obj1->getId() == obj2->getId()) return obj1; /* * Special case: run-time DNSName object with source name "self" * matches firewall. */ MultiAddressRunTime *mart = MultiAddressRunTime::cast(obj2); if (mart) { if (mart->getSubstitutionTypeName() == DNSName::TYPENAME && mart->getSourceName() == "self") return obj1; } /* * match only if all interfaces of obj1 match obj2 */ return dispatch(static_cast<Host*>(obj1), obj2); }
void NATCompiler_pf::PrintRule::_printAddr(FWObject *o) { MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { compiler->output << atrt->getSourceName() << " "; return; } if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { compiler->output << "<" << o->getName() << "> "; return; } if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME) { compiler->output << atrt->getSourceName() << ":network "; return ; } assert(atrt==NULL); } if (Interface::cast(o)!=NULL) { compiler->output << "(" << o->getName() << ") "; return; } if (o->getBool("pf_table")) { compiler->output << "<" << o->getName() << "> "; return; } Address *addr_obj = Address::cast(o); assert(addr_obj!=NULL); const InetAddr *addr = addr_obj->getAddressPtr(); if (addr) { InetAddr mask = *(addr_obj->getNetmaskPtr()); if (Interface::cast(o)!=NULL || Address::cast(o)->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } if (addr->isAny() && mask.isAny()) { compiler->output << "any "; } else { compiler->output << addr->toString(); if (!mask.isHostMask()) { compiler->output << "/" << mask.getLength(); } compiler->output << " "; } } }
string TableFactory::PrintTables() { if (tables.size() == 0) return ""; stringstream output; output << endl; output << "# Tables: (" << tables.size() << ")" << endl; for (map<string,string>::const_iterator i=tblnames.begin(); i!=tblnames.end(); i++) { string tblID = i->second; FWObject *grp = tables[tblID]; output << "table "; output << "<" << grp->getName() << "> "; MultiAddressRunTime *atrt = MultiAddressRunTime::cast(grp); if (atrt!=nullptr && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { output << "persist"; if ( !atrt->getSourceName().empty() ) { string path = atrt->getSourceNameAsPath(firewall->getOptionsObject()); if (path.empty()) { compiler->abort("Error: Firewall's data directory not set for address table: " + atrt->getName()); } output << " file \"" << path << "\""; } output << endl; continue; } output << "{ "; for (FWObject::iterator i=grp->begin(); i!=grp->end(); i++) { if (i!=grp->begin()) output << ", "; FWObject *o = FWReference::getObject(*i); if (o==nullptr) compiler->abort("broken table object "); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=nullptr) { if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) { output << atrt->getSourceName() << " "; } if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME) { output << atrt->getSourceName() << ":network "; } } else { if (Interface::cast(o)) { output << o->getName(); } else { Address *A=Address::cast( o ); if (A==nullptr) compiler->abort("table object must be an address: '" + o->getTypeName()+"'"); const InetAddr *addr = A->getAddressPtr(); InetAddr mask = *(A->getNetmaskPtr()); if (A->dimension()==1) { mask = InetAddr(InetAddr::getAllOnes()); } output << addr->toString(); if (!mask.isHostMask()) { output << "/" << mask.getLength(); } } } output << " "; } output << "} "; output << endl; } output << endl; return output.str(); }
bool PolicyCompiler_pf::processMultiAddressObjectsInRE::processNext() { PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); bool neg = re->getNeg(); list<FWObject*> maddr_runtime; try { for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o); if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { if (re->size()>1 && neg) { compiler->abort(rule, "AddressTable object can not be used " "with negation in combination with " "other objects in the same rule element."); } string tblname = o->getName(); string tblID = tblname + "_addressTableObject"; pf_comp->tables->registerTable(tblname,tblID,o); o->setBool("pf_table",true); maddr_runtime.push_back(o); } } } catch(FWException &ex) // TableFactory::registerTable throws exception { string err; err = "Can not process MultiAddress object: " + ex.toString(); compiler->abort(rule, err); } if (!maddr_runtime.empty()) { RuleElement *nre; for (FWObject::iterator i=maddr_runtime.begin(); i!=maddr_runtime.end(); i++) { PolicyRule *r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( *i ); tmp_queue.push_back(r); } for (FWObject::iterator i=maddr_runtime.begin(); i!=maddr_runtime.end(); i++) re->removeRef( *i ); if (!re->isAny()) tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; }
/* * this is very much like * Compiler::swapMultiAddressObjectsInRE::processNext() except it also * registers the table using registerTable() */ bool PolicyCompiler_pf::swapAddressTableObjectsInRE::processNext() { PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler); Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false; RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) ); list<MultiAddress*> cl; for (FWObject::iterator i=re->begin(); i!=re->end(); i++) { FWObject *o= *i; if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer(); /* * All addressTable objects will be run-time here because we * switch them in preprocessor. The difference is: if address * table was originally run-time, at this point it will have * no children, however if it was compile-time originally, it * will have children objects. That is how we distinguish * them in this rule processor. Here we only deal with * AddressTable objects that originally used to be * compile-time because we need to create tables for them. */ if (AddressTable::cast(o)!=NULL && AddressTable::cast(o)->isRunTime() && o->size() > 0) cl.push_back(MultiAddress::cast(o)); } if (!cl.empty()) { for (list<MultiAddress*>::iterator i=cl.begin(); i!=cl.end(); i++) { MultiAddress *atbl = *i; // Need to make sure the ID of the MultiAddressRunTime // object created here is stable and is always the same // for the same MultiAddress object. In particular this // ensures that we reuse tables between policy and NAT rules string mart_id_str = FWObjectDatabase::getStringId(atbl->getId()) + "_runtime"; int mart_id = FWObjectDatabase::registerStringId(mart_id_str); MultiAddressRunTime *mart = MultiAddressRunTime::cast(compiler->dbcopy->findInIndex(mart_id)); if (mart==NULL) { mart = new MultiAddressRunTime(atbl); // need to ensure stable ID for the runtime object, so // that when the same object is replaced in different // rulesets by different compiler passes, chosen // runtime object has the same ID and is identified as // the same by the compiler. mart->setId( mart_id ); compiler->dbcopy->addToIndex(mart); compiler->persistent_objects->add(mart); // register this object as a table string tblname = atbl->getName(); string tblID = tblname + "_addressTableObject"; pf_comp->tables->registerTable(tblname,tblID,atbl); } re->removeRef(atbl); re->addRef(mart); } tmp_queue.push_back(rule); return true; } tmp_queue.push_back(rule); return true; }