mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-03-25 12:47:44 +01:00
see #1942 refactored rule processors that deal with service so that they can be used by both policy and nat compilers
This commit is contained in:
parent
5efb7ae3e5
commit
568e222fa5
@ -512,6 +512,163 @@ protected:
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* split rules with more than one service object, so that each
|
||||
* rule has services with the same protocol
|
||||
*/
|
||||
class splitServices : public BasicRuleProcessor
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
splitServices(const std::string &name) : BasicRuleProcessor(name) {}
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* separate service object that satisfies condition
|
||||
* implemented in the virtual method "condition" so we have
|
||||
* exactly one such object per rule.
|
||||
*/
|
||||
class separateServiceObject : public BasicRuleProcessor
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv) =0;
|
||||
public:
|
||||
separateServiceObject(const std::string &name);
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* separate TCP/UDP services that specify source port (can
|
||||
* not be used in combination with destination port with
|
||||
* multiport)
|
||||
*/
|
||||
class separateSrcPort : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateSrcPort(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate Tag services so we have exactly one per rule.
|
||||
*/
|
||||
class separateTagged : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateTagged(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
class separateUserServices : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateUserServices(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate IPService objects with tos attrubute so we have
|
||||
* exactly one per rule.
|
||||
*/
|
||||
class separateTOS : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateTOS(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* split rules with more than one IPService object with
|
||||
* options, so that each rule has only one such service
|
||||
*/
|
||||
class splitIpOptions : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
splitIpOptions(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate TCP services with flags (can't use those in combination
|
||||
* with others in groups of services)
|
||||
*/
|
||||
class separateTCPWithFlags : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateTCPWithFlags(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate TCP and UDP services that match port ranges and
|
||||
* "any tcp" or "any udp" objects
|
||||
*/
|
||||
class separatePortRanges : public separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separatePortRanges(const std::string &name) :
|
||||
separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* verify if custom services used in rules are configured for
|
||||
* this platform
|
||||
*/
|
||||
class verifyCustomServices : public BasicRuleProcessor
|
||||
{
|
||||
public:
|
||||
verifyCustomServices(const std::string &name) :
|
||||
BasicRuleProcessor(name) {}
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* simply check if TCPService object with "established" flag
|
||||
* set is used in Service and abort with an error saying that
|
||||
* target firewall does not support this. Use for pretty much
|
||||
* every platform except ipfw and router ACLs
|
||||
*/
|
||||
class CheckForTCPEstablished : public BasicRuleProcessor
|
||||
{
|
||||
public:
|
||||
CheckForTCPEstablished(const std::string &name) :
|
||||
BasicRuleProcessor(name) {}
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* simply check if UserService objectis used in Service and
|
||||
* abort with an error saying that target firewall does not
|
||||
* support this.
|
||||
*/
|
||||
class CheckForUnsupportedUserService : public BasicRuleProcessor
|
||||
{
|
||||
public:
|
||||
CheckForUnsupportedUserService(const std::string &name) :
|
||||
BasicRuleProcessor(name) {}
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* prepare interface string
|
||||
*/
|
||||
|
||||
@ -226,120 +226,6 @@ namespace fwcompiler {
|
||||
*/
|
||||
DECLARE_POLICY_RULE_PROCESSOR(addressRanges);
|
||||
|
||||
/**
|
||||
* split rules with more than one service object, so that each
|
||||
* rule has services with the same protocol
|
||||
*/
|
||||
DECLARE_POLICY_RULE_PROCESSOR(splitServices);
|
||||
|
||||
|
||||
/**
|
||||
* separate service object that satisfies condition
|
||||
* implemented in the virtual method "condition" so we have
|
||||
* exactly one such object per rule.
|
||||
*/
|
||||
class separateServiceObject : public PolicyRuleProcessor
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv) =0;
|
||||
public:
|
||||
separateServiceObject(const std::string &name);
|
||||
virtual bool processNext();
|
||||
};
|
||||
|
||||
/**
|
||||
* separate TCP/UDP services that specify source port (can
|
||||
* not be used in combination with destination port with
|
||||
* multiport)
|
||||
*/
|
||||
class separateSrcPort : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateSrcPort(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate Tag services so we have exactly one per rule.
|
||||
*/
|
||||
class separateTagged : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateTagged(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
class separateUserServices : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateUserServices(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate IPService objects with tos attrubute so we have
|
||||
* exactly one per rule.
|
||||
*/
|
||||
class separateTOS : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateTOS(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* split rules with more than one IPService object with
|
||||
* options, so that each rule has only one such service
|
||||
*/
|
||||
class splitIpOptions : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
splitIpOptions(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate TCP services with flags (can't use those in combination
|
||||
* with others in groups of services)
|
||||
*/
|
||||
class separateTCPWithFlags : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separateTCPWithFlags(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* separate TCP and UDP services that match port ranges and
|
||||
* "any tcp" or "any udp" objects
|
||||
*/
|
||||
class separatePortRanges : public PolicyCompiler::separateServiceObject
|
||||
{
|
||||
protected:
|
||||
virtual bool condition(const libfwbuilder::Service *srv);
|
||||
public:
|
||||
separatePortRanges(const std::string &name) :
|
||||
PolicyCompiler::separateServiceObject(name) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* verify if custom services used in rules are configured for
|
||||
* this platform
|
||||
*/
|
||||
DECLARE_POLICY_RULE_PROCESSOR(verifyCustomServices);
|
||||
|
||||
/**
|
||||
* checks for unnumbered interface in rule elements (one can
|
||||
@ -370,21 +256,6 @@ namespace fwcompiler {
|
||||
*/
|
||||
DECLARE_POLICY_RULE_PROCESSOR(ConvertToAtomic);
|
||||
|
||||
/**
|
||||
* simply check if TCPService object with "established" flag
|
||||
* set is used in Service and abort with an error saying that
|
||||
* target firewall does not support this. Use for pretty much
|
||||
* every platform except ipfw and router ACLs
|
||||
*/
|
||||
DECLARE_POLICY_RULE_PROCESSOR(CheckForTCPEstablished);
|
||||
|
||||
/**
|
||||
* simply check if UserService objectis used in Service and
|
||||
* abort with an error saying that target firewall does not
|
||||
* support this.
|
||||
*/
|
||||
DECLARE_POLICY_RULE_PROCESSOR(CheckForUnsupportedUserService);
|
||||
|
||||
/**
|
||||
* drop rules that have ipv4 or ipv6 addresses (depending
|
||||
* on the argument ipv6 passed to the constructor)
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "PolicyCompiler.h"
|
||||
#include "Compiler.h"
|
||||
|
||||
#include "fwbuilder/RuleElement.h"
|
||||
#include "fwbuilder/IPService.h"
|
||||
@ -50,14 +50,19 @@ using namespace libfwbuilder;
|
||||
using namespace std;
|
||||
|
||||
|
||||
/*
|
||||
* These rule processors should work for both Policy and NAT rules
|
||||
* without having to build specialized classes inheriting from these.
|
||||
*/
|
||||
|
||||
bool PolicyCompiler::splitServices::processNext()
|
||||
bool Compiler::splitServices::processNext()
|
||||
{
|
||||
PolicyRule *rule=getNext(); if (rule==NULL) return false;
|
||||
Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false;
|
||||
string re_type = PolicyRule::isA(rule) ?
|
||||
RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME;
|
||||
RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type));
|
||||
|
||||
RuleElementSrv *srv=rule->getSrv();
|
||||
|
||||
if (srv->size()==1)
|
||||
if (re_srv->size()==1)
|
||||
{
|
||||
tmp_queue.push_back(rule);
|
||||
return true;
|
||||
@ -65,11 +70,9 @@ bool PolicyCompiler::splitServices::processNext()
|
||||
|
||||
map<int, list<Service*> > services;
|
||||
|
||||
for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++)
|
||||
for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++)
|
||||
{
|
||||
FWObject *o = FWReference::getObject(*i);
|
||||
|
||||
Service *s=Service::cast( o );
|
||||
Service *s = Service::cast(FWReference::getObject(*i));
|
||||
assert(s);
|
||||
|
||||
int proto = s->getProtocolNumber();
|
||||
@ -81,10 +84,10 @@ bool PolicyCompiler::splitServices::processNext()
|
||||
{
|
||||
list<Service*> &sl=(*i1).second;
|
||||
|
||||
PolicyRule *r= compiler->dbcopy->createPolicyRule();
|
||||
PolicyRule *r = compiler->dbcopy->createPolicyRule();
|
||||
compiler->temp_ruleset->add(r);
|
||||
r->duplicate(rule);
|
||||
RuleElementSrv *nsrv=r->getSrv();
|
||||
RuleElement *nsrv = RuleElement::cast(r->getFirstByType(re_type));
|
||||
nsrv->clearChildren();
|
||||
|
||||
for (list<Service*>::iterator j=sl.begin(); j!=sl.end(); j++)
|
||||
@ -99,24 +102,26 @@ bool PolicyCompiler::splitServices::processNext()
|
||||
|
||||
|
||||
|
||||
PolicyCompiler::separateServiceObject::separateServiceObject(
|
||||
const string &name) : PolicyRuleProcessor(name)
|
||||
Compiler::separateServiceObject::separateServiceObject(
|
||||
const string &name) : BasicRuleProcessor(name)
|
||||
{
|
||||
}
|
||||
|
||||
bool PolicyCompiler::separateServiceObject::processNext()
|
||||
bool Compiler::separateServiceObject::processNext()
|
||||
{
|
||||
PolicyRule *rule=getNext(); if (rule==NULL) return false;
|
||||
Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false;
|
||||
string re_type = PolicyRule::isA(rule) ?
|
||||
RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME;
|
||||
RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type));
|
||||
|
||||
RuleElementSrv *rel= rule->getSrv();
|
||||
|
||||
if (rel->size()==1) {
|
||||
if (re_srv->size()==1)
|
||||
{
|
||||
tmp_queue.push_back(rule);
|
||||
return true;
|
||||
}
|
||||
|
||||
list<Service*> services;
|
||||
for (FWObject::iterator i=rel->begin(); i!=rel->end(); i++)
|
||||
for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++)
|
||||
{
|
||||
FWObject *o= *i;
|
||||
if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
|
||||
@ -128,7 +133,7 @@ bool PolicyCompiler::separateServiceObject::processNext()
|
||||
PolicyRule *r = compiler->dbcopy->createPolicyRule();
|
||||
compiler->temp_ruleset->add(r);
|
||||
r->duplicate(rule);
|
||||
RuleElementSrv *nsrv=r->getSrv();
|
||||
RuleElement *nsrv = RuleElement::cast(r->getFirstByType(re_type));
|
||||
nsrv->clearChildren();
|
||||
nsrv->addRef( s );
|
||||
tmp_queue.push_back(r);
|
||||
@ -136,9 +141,9 @@ bool PolicyCompiler::separateServiceObject::processNext()
|
||||
}
|
||||
}
|
||||
for (list<Service*>::iterator i=services.begin(); i!=services.end(); i++)
|
||||
rel->removeRef( (*i) );
|
||||
re_srv->removeRef( (*i) );
|
||||
|
||||
if (!rel->isAny())
|
||||
if (!re_srv->isAny())
|
||||
tmp_queue.push_back(rule);
|
||||
|
||||
return true;
|
||||
@ -150,7 +155,7 @@ bool PolicyCompiler::separateServiceObject::processNext()
|
||||
* not be used in combination with destination port with
|
||||
* multiport)
|
||||
*/
|
||||
bool PolicyCompiler::separateSrcPort::condition(const Service *srv)
|
||||
bool Compiler::separateSrcPort::condition(const Service *srv)
|
||||
{
|
||||
if ( TCPService::isA(srv) || UDPService::isA(srv))
|
||||
{
|
||||
@ -164,35 +169,35 @@ bool PolicyCompiler::separateSrcPort::condition(const Service *srv)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PolicyCompiler::separateTagged::condition(const Service *srv)
|
||||
bool Compiler::separateTagged::condition(const Service *srv)
|
||||
{
|
||||
return ( TagService::isA(srv));
|
||||
}
|
||||
|
||||
bool PolicyCompiler::separateUserServices::condition(const Service *srv)
|
||||
bool Compiler::separateUserServices::condition(const Service *srv)
|
||||
{
|
||||
return ( UserService::isA(srv));
|
||||
}
|
||||
|
||||
bool PolicyCompiler::separateTOS::condition(const Service *srv)
|
||||
bool Compiler::separateTOS::condition(const Service *srv)
|
||||
{
|
||||
const IPService *ip = IPService::constcast(srv);
|
||||
return (ip && !ip->getTOSCode().empty());
|
||||
}
|
||||
|
||||
bool PolicyCompiler::splitIpOptions::condition(const Service *srv)
|
||||
bool Compiler::splitIpOptions::condition(const Service *srv)
|
||||
{
|
||||
const IPService *ip = IPService::constcast(srv);
|
||||
return (ip && ip->hasIpOptions());
|
||||
}
|
||||
|
||||
bool PolicyCompiler::separateTCPWithFlags::condition(const Service *srv)
|
||||
bool Compiler::separateTCPWithFlags::condition(const Service *srv)
|
||||
{
|
||||
const TCPService *s = TCPService::constcast(srv);
|
||||
return (s && s->inspectFlags() );
|
||||
}
|
||||
|
||||
bool PolicyCompiler::separatePortRanges::condition(const Service *srv)
|
||||
bool Compiler::separatePortRanges::condition(const Service *srv)
|
||||
{
|
||||
if ( TCPService::isA(srv) || UDPService::isA(srv) )
|
||||
{
|
||||
@ -226,15 +231,16 @@ bool PolicyCompiler::separatePortRanges::condition(const Service *srv)
|
||||
|
||||
|
||||
|
||||
bool PolicyCompiler::verifyCustomServices::processNext()
|
||||
bool Compiler::verifyCustomServices::processNext()
|
||||
{
|
||||
PolicyRule *rule=getNext(); if (rule==NULL) return false;
|
||||
Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false;
|
||||
string re_type = PolicyRule::isA(rule) ?
|
||||
RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME;
|
||||
RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type));
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
|
||||
RuleElementSrv *srv=rule->getSrv();
|
||||
|
||||
for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++)
|
||||
for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++)
|
||||
{
|
||||
FWObject *o = FWReference::getObject(*i);
|
||||
assert(o!=NULL);
|
||||
@ -246,16 +252,14 @@ bool PolicyCompiler::verifyCustomServices::processNext()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool PolicyCompiler::CheckForTCPEstablished::processNext()
|
||||
bool Compiler::CheckForTCPEstablished::processNext()
|
||||
{
|
||||
PolicyRule *rule=getNext(); if (rule==NULL) return false;
|
||||
Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false;
|
||||
string re_type = PolicyRule::isA(rule) ?
|
||||
RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME;
|
||||
RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type));
|
||||
|
||||
RuleElementSrv *srv=rule->getSrv();
|
||||
|
||||
for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++)
|
||||
for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++)
|
||||
{
|
||||
FWObject *o = FWReference::getObject(*i);
|
||||
|
||||
@ -264,34 +268,33 @@ bool PolicyCompiler::CheckForTCPEstablished::processNext()
|
||||
|
||||
if (s->getEstablished())
|
||||
compiler->abort(
|
||||
|
||||
rule,
|
||||
string("TCPService object with option \"established\" "
|
||||
"is not supported by firewall platform \"") +
|
||||
compiler->myPlatformName() +
|
||||
string("\". Use stateful rule instead."));
|
||||
rule,
|
||||
string("TCPService object with option \"established\" "
|
||||
"is not supported by firewall platform \"") +
|
||||
compiler->myPlatformName() +
|
||||
string("\". Use stateful rule instead."));
|
||||
}
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PolicyCompiler::CheckForUnsupportedUserService::processNext()
|
||||
bool Compiler::CheckForUnsupportedUserService::processNext()
|
||||
{
|
||||
PolicyRule *rule=getNext(); if (rule==NULL) return false;
|
||||
Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false;
|
||||
string re_type = PolicyRule::isA(rule) ?
|
||||
RuleElementSrv::TYPENAME : RuleElementOSrv::TYPENAME;
|
||||
RuleElement *re_srv = RuleElement::cast(rule->getFirstByType(re_type));
|
||||
|
||||
RuleElementSrv *srv=rule->getSrv();
|
||||
|
||||
for (FWObject::iterator i=srv->begin(); i!=srv->end(); i++)
|
||||
for (FWObject::iterator i=re_srv->begin(); i!=re_srv->end(); i++)
|
||||
{
|
||||
FWObject *o = FWReference::getObject(*i);
|
||||
|
||||
if (UserService::isA(o))
|
||||
compiler->abort(
|
||||
|
||||
rule,
|
||||
string("UserService object is not supported by ") +
|
||||
compiler->myPlatformName());
|
||||
rule,
|
||||
string("UserService object is not supported by ") +
|
||||
compiler->myPlatformName());
|
||||
}
|
||||
|
||||
tmp_queue.push_back(rule);
|
||||
@ -15,7 +15,7 @@ SOURCES = BaseCompiler.cpp \
|
||||
NATCompiler.cpp \
|
||||
OSConfigurator.cpp \
|
||||
PolicyCompiler.cpp \
|
||||
PolicyCompiler_srvre_functions.cpp \
|
||||
ServiceRuleProcessors.cpp \
|
||||
RoutingCompiler.cpp
|
||||
|
||||
HEADERS = BaseCompiler.h \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user