diff --git a/src/cisco_lib/NATCompiler_asa8.cpp b/src/cisco_lib/NATCompiler_asa8.cpp index 46d0ff0a6..b4fa7604a 100644 --- a/src/cisco_lib/NATCompiler_asa8.cpp +++ b/src/cisco_lib/NATCompiler_asa8.cpp @@ -352,6 +352,9 @@ void NATCompiler_asa8::compile() add( new VerifyValidityOfDNSOption( "Check validity of 'translate dns' option")); + + //add( new groupTCPUDP("split rules with TCP or UDP services")); + add( new SpecialServicesOSrv( "check for special services" )); add( new CreateObjectGroupsForOSrc("create object groups for OSrc")); diff --git a/src/cisco_lib/PolicyCompiler_iosacl.cpp b/src/cisco_lib/PolicyCompiler_iosacl.cpp index fa9f49e5f..006c6c7e5 100644 --- a/src/cisco_lib/PolicyCompiler_iosacl.cpp +++ b/src/cisco_lib/PolicyCompiler_iosacl.cpp @@ -387,7 +387,7 @@ void PolicyCompiler_iosacl::compile() add( new InterfacePolicyRules( "process interface policy rules and store interface ids") ); - add( new splitServices ("split rules with different protocols" ) ); + add( new groupServicesByProtocol ("split rules with different protocols" ) ); add( new ExpandMultipleAddressesInSrc( "expand objects with multiple addresses in SRC" ) ); diff --git a/src/cisco_lib/PolicyCompiler_pix.cpp b/src/cisco_lib/PolicyCompiler_pix.cpp index 696c1d452..2d9dd179f 100644 --- a/src/cisco_lib/PolicyCompiler_pix.cpp +++ b/src/cisco_lib/PolicyCompiler_pix.cpp @@ -540,8 +540,10 @@ void PolicyCompiler_pix::compile() if (XMLTools::version_compare(vers, "8.0")<0) { - add( new splitServices("split rules with different protocols" )); - } + add( new groupServicesByProtocol("split rules with different protocols")); + } + //else + // add( new groupTCPUDP("split rules with TCP or UDP services")); add( new PrepareForICMPCmd("prepare for icmp command" )); diff --git a/src/cisco_lib/PolicyCompiler_pix_writers.cpp b/src/cisco_lib/PolicyCompiler_pix_writers.cpp index a9ef6e64f..24d5d6c82 100644 --- a/src/cisco_lib/PolicyCompiler_pix_writers.cpp +++ b/src/cisco_lib/PolicyCompiler_pix_writers.cpp @@ -521,13 +521,14 @@ bool PolicyCompiler_pix::PrintRule::processNext() aclstr << _printAction(rule); /* - * processor splitServices guaranties that rule has services of - * the same type (that is, the same protocol, like all tcp, all - * udp, all icmp or all IP with the same protocol number). PIX can - * use object-group for protocol only if protocol numbers are - * different and these are not icmp/tcp/udp protocols. This means - * that because of processor splitServices we never use - * object-group in protocol part of ACL. + * processor groupServicesByProtocol guaranties that rule has + * services of the same type (that is, the same protocol, like all + * tcp, all udp, all icmp or all IP with the same protocol + * number). PIX can use object-group for protocol only if protocol + * numbers are different and these are not icmp/tcp/udp + * protocols. This means that because of processor + * groupServicesByProtocol we never use object-group in protocol + * part of ACL. */ PIXObjectGroup *pgsrv = PIXObjectGroup::cast(srvobj); diff --git a/src/iptlib/PolicyCompiler_ipt.cpp b/src/iptlib/PolicyCompiler_ipt.cpp index af854834e..97d0ed675 100644 --- a/src/iptlib/PolicyCompiler_ipt.cpp +++ b/src/iptlib/PolicyCompiler_ipt.cpp @@ -3653,7 +3653,7 @@ bool PolicyCompiler_ipt::splitServicesIfRejectWithTCPReset::processNext() } /* - * processor splitServices should have been called eariler, so now all + * processor groupServicesByProtocol should have been called eariler, so now all * services in Srv are of the same type */ bool PolicyCompiler_ipt::prepareForMultiport::processNext() @@ -3731,7 +3731,7 @@ bool PolicyCompiler_ipt::prepareForMultiport::processNext() } /* - * processor splitServices should have been called before, it makes sure + * processor groupServicesByProtocol should have been called before, it makes sure * all objects in Service are of the same type. * * One special case is custom service "ESTABLISHED". This processor @@ -4404,17 +4404,16 @@ void PolicyCompiler_ipt::compile() add( new bridgingFw("handle bridging firewall cases")); add( new specialCaseWithUnnumberedInterface( - "check for a special cases with unnumbered interface" ) ); + "check for a special cases with unnumbered interface")); -// add( new splitServices( "split on services" ) ); -// add( new prepareForMultiport("prepare for multiport" ) ); +// add( new groupServicesByProtocol("split on services")); +// add( new prepareForMultiport("prepare for multiport")); - add( new optimize1( "optimization 1, pass 1" ) ); - add( new optimize1( "optimization 1, pass 2" ) ); - add( new optimize1( "optimization 1, pass 3" ) ); + add( new optimize1("optimization 1, pass 1")); + add( new optimize1("optimization 1, pass 2")); + add( new optimize1("optimization 1, pass 3")); - - add( new splitServices("split on services")); + add( new groupServicesByProtocol("split on services")); add( new separateTCPWithFlags("split on TCP services with flags")); add( new verifyCustomServices("verify custom services")); add( new specialCasesWithCustomServices( diff --git a/src/libfwbuilder/src/fwcompiler/Compiler.h b/src/libfwbuilder/src/fwcompiler/Compiler.h index 3748aedd4..cc6d4853d 100644 --- a/src/libfwbuilder/src/fwcompiler/Compiler.h +++ b/src/libfwbuilder/src/fwcompiler/Compiler.h @@ -512,19 +512,32 @@ protected: virtual bool processNext(); }; + /** + * split rules with more than one service object, so that each + * rule has services that satisfy some common criteria defined by + * the virtual function groupingCode() + */ + class groupServices : public BasicRuleProcessor + { + protected: + virtual int groupingCode(const libfwbuilder::Service *srv) =0; + public: + groupServices(const std::string &name) : BasicRuleProcessor(name) {} + 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 + class groupServicesByProtocol: public groupServices { protected: + virtual int groupingCode(const libfwbuilder::Service *srv); public: - splitServices(const std::string &name) : BasicRuleProcessor(name) {} - virtual bool processNext(); + groupServicesByProtocol(const std::string &name) : groupServices(name){} }; - + /** * separate service object that satisfies condition * implemented in the virtual method "condition" so we have @@ -539,6 +552,19 @@ protected: virtual bool processNext(); }; + /** + * separate TCP/UDP services (regardless of their source or + * destination port configuration) + */ + class separateTCPUDP : public separateServiceObject + { + protected: + virtual bool condition(const libfwbuilder::Service *srv); + public: + separateTCPUDP(const std::string &name) : + separateServiceObject(name) {} + }; + /** * separate TCP/UDP services that specify source port (can * not be used in combination with destination port with diff --git a/src/libfwbuilder/src/fwcompiler/ServiceRuleProcessors.cpp b/src/libfwbuilder/src/fwcompiler/ServiceRuleProcessors.cpp index a410737da..51f5b4711 100644 --- a/src/libfwbuilder/src/fwcompiler/ServiceRuleProcessors.cpp +++ b/src/libfwbuilder/src/fwcompiler/ServiceRuleProcessors.cpp @@ -55,7 +55,7 @@ using namespace std; * without having to build specialized classes inheriting from these. */ -bool Compiler::splitServices::processNext() +bool Compiler::groupServices::processNext() { Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false; string re_type = PolicyRule::isA(rule) ? @@ -75,7 +75,7 @@ bool Compiler::splitServices::processNext() Service *s = Service::cast(FWReference::getObject(*i)); assert(s); - int proto = s->getProtocolNumber(); + int proto = groupingCode(s); services[proto].push_back(s); } @@ -100,7 +100,10 @@ bool Compiler::splitServices::processNext() return true; } - +int Compiler::groupServicesByProtocol::groupingCode(const Service *srv) +{ + return srv->getProtocolNumber(); +} Compiler::separateServiceObject::separateServiceObject( const string &name) : BasicRuleProcessor(name) @@ -186,6 +189,11 @@ bool Compiler::separateSrcAndDstPort::condition(const Service *srv) return false; } +bool Compiler::separateTCPUDP::condition(const Service *srv) +{ + return ( TCPService::isA(srv) || UDPService::isA(srv)); +} + bool Compiler::separateTagged::condition(const Service *srv) { return ( TagService::isA(srv)); diff --git a/src/pflib/PolicyCompiler_ipf.cpp b/src/pflib/PolicyCompiler_ipf.cpp index 5f10bc6ae..fa74e3f4b 100644 --- a/src/pflib/PolicyCompiler_ipf.cpp +++ b/src/pflib/PolicyCompiler_ipf.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "PolicyCompiler_ipf.h" +#include "fwcompiler/Compiler.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" @@ -526,7 +527,7 @@ void PolicyCompiler_ipf::compile() add( new specialCaseWithDynInterface( "check for a special cases with dynamic interface") ); add( new addressRanges("expand address range objects") ); - add( new splitServices("split rules with different protocols") ); + add( new groupServicesByProtocol("split rules with different protocols") ); add( new separateTCPWithFlags("separate TCP services with flags" ) ); add( new separateSrcPort("split on TCP and UDP with source ports")); add( new verifyCustomServices( diff --git a/src/pflib/PolicyCompiler_ipfw.cpp b/src/pflib/PolicyCompiler_ipfw.cpp index e3f2b809d..15bf9addd 100644 --- a/src/pflib/PolicyCompiler_ipfw.cpp +++ b/src/pflib/PolicyCompiler_ipfw.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "PolicyCompiler_ipfw.h" +#include "fwcompiler/Compiler.h" #include "fwbuilder/FWObjectDatabase.h" #include "fwbuilder/RuleElement.h" @@ -633,7 +634,7 @@ void PolicyCompiler_ipfw::compile() add( new specialCaseWithDynInterface( "check for a special cases with dynamic interface")); add( new addressRanges("expand address range objects")); - add( new splitServices("split rules with different protocols")); + add( new groupServicesByProtocol("split rules with different protocols")); add( new splitIpOptions("split rules with multiple IPService objects with options")); add( new separateTCPWithFlags("separate TCP services with flags")); add( new separateSrcPort("split on TCP and UDP with source ports")); diff --git a/src/pflib/PolicyCompiler_pf.cpp b/src/pflib/PolicyCompiler_pf.cpp index deddba9a8..9f3ea5523 100644 --- a/src/pflib/PolicyCompiler_pf.cpp +++ b/src/pflib/PolicyCompiler_pf.cpp @@ -1048,7 +1048,7 @@ void PolicyCompiler_pf::compile() add(new MACFiltering("verify for MAC address filtering")); add(new checkForUnnumbered("check for unnumbered interfaces")); add(new addressRanges("expand address range objects")); - add(new splitServices("split rules with different protocols")); + add(new groupServicesByProtocol("split rules with different protocols")); add(new separateTCPWithFlags("separate TCP services with flags")); add(new separateSrcPort("split on TCP and UDP with source ports")); add(new separateTagged("split on TagService")); diff --git a/src/pflib/PolicyCompiler_pf_writers.cpp b/src/pflib/PolicyCompiler_pf_writers.cpp index 88b23a8fd..a2fb66212 100644 --- a/src/pflib/PolicyCompiler_pf_writers.cpp +++ b/src/pflib/PolicyCompiler_pf_writers.cpp @@ -980,9 +980,10 @@ bool PolicyCompiler_pf::PrintRule::processNext() * Dealing with "keep state" and "modulate state" flags * * 1. both flags do not apply to deny/reject rules. - * 2. modulate state applies only to TCP services. Since we use splitServices, - * all services in a rule are of the same protocol, therefore we can simply - * check type of srv + * + * 2. modulate state applies only to TCP services. Since we use + * groupServicesByProtocol, all services in a rule are of the same + * protocol, therefore we can simply check type of srv */ if ( ! ruleopt->getBool("stateless") ) {