mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-03-23 03:37:15 +01:00
remove copies of cluster interfaces form the member firewall after all checks are done: fixes #636 ; automatically make vlan parent inetrfaces unprotected and issue warning; check for uniquenness of labels;
This commit is contained in:
parent
b91a939404
commit
6d9f994067
@ -80,6 +80,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QtDebug>
|
||||
|
||||
|
||||
using namespace std;
|
||||
@ -259,71 +260,55 @@ string CompilerDriver_pix::run(const std::string &cluster_id,
|
||||
|
||||
multimap<string, FWObject*> netzone_objects;
|
||||
|
||||
std::list<FWObject*> l2=fw->getByType(Interface::TYPENAME);
|
||||
for (std::list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i)
|
||||
std::list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);
|
||||
for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i)
|
||||
{
|
||||
Interface *iface = dynamic_cast<Interface*>(*i);
|
||||
assert(iface);
|
||||
|
||||
if (iface->getOptionsObject()->getBool("cluster_interface")) continue;
|
||||
|
||||
if ((iface->getOptionsObject()->getStr("type") == "" ||
|
||||
iface->getOptionsObject()->getStr("type") == "ethernet") &&
|
||||
iface->getByType(Interface::TYPENAME).size() > 0)
|
||||
{
|
||||
// Parent vlan interface (i.e. trunk)
|
||||
if (!iface->isUnprotected())
|
||||
{
|
||||
QString err(
|
||||
"Interface %1 has vlan subinterfaces, it can not "
|
||||
"be used for ACL. Marking this interface \"unprotected\" "
|
||||
"to exclude it."
|
||||
);
|
||||
warning(fw, NULL, NULL,
|
||||
err.arg(iface->getName().c_str())
|
||||
.toStdString());
|
||||
iface->setUnprotected(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for label, security level and network zone make sense
|
||||
// only for interfaces that can be used in ACLs or to bind
|
||||
// ACLs to. Unnumbered interfaces can't, so we do not need to
|
||||
// run these checks. One example of unnumbered interface is
|
||||
// parent interface for vlan subinterfaces.
|
||||
if (iface->isUnnumbered()) continue;
|
||||
|
||||
if (iface->getOptionsObject()->getBool("cluster_interface")) continue;
|
||||
if (iface->isUnprotected()) continue;
|
||||
|
||||
/*
|
||||
* missing labels on interfaces
|
||||
* there shouldn't be two interfaces with the same security level and same label
|
||||
*
|
||||
*/
|
||||
if (iface->getLabel()=="")
|
||||
{
|
||||
string lbl;
|
||||
if (iface->isDedicatedFailover())
|
||||
{
|
||||
// dedicated failover interface misses label. This
|
||||
// interface can be used in failover cluster group
|
||||
// or state sync group. Assign label depending on
|
||||
// the function.
|
||||
FWObjectTypedChildIterator it =
|
||||
cluster->findByType(StateSyncClusterGroup::TYPENAME);
|
||||
StateSyncClusterGroup *state_sync_group =
|
||||
StateSyncClusterGroup::cast(*it);
|
||||
if (state_sync_group && state_sync_group->hasMember(iface))
|
||||
lbl = "state";
|
||||
|
||||
if (!iface->getOptionsObject()->getStr("failover_group_id").empty())
|
||||
lbl = "failover";
|
||||
}
|
||||
|
||||
if (lbl.empty())
|
||||
{
|
||||
if (iface->getSecurityLevel()==0) lbl="outside";
|
||||
else
|
||||
{
|
||||
if (iface->getSecurityLevel()==100) lbl="inside";
|
||||
else
|
||||
{
|
||||
QString l("dmz%1");
|
||||
lbl = l.arg(iface->getSecurityLevel()).toStdString();
|
||||
}
|
||||
}
|
||||
}
|
||||
iface->setLabel(lbl);
|
||||
}
|
||||
|
||||
/*
|
||||
* there shouldn't be two interfaces with the same security level
|
||||
*/
|
||||
for (std::list<FWObject*>::iterator j=l2.begin(); j!=l2.end(); ++j)
|
||||
for (std::list<FWObject*>::iterator j=all_interfaces.begin(); j!=all_interfaces.end(); ++j)
|
||||
{
|
||||
Interface *iface2 = dynamic_cast<Interface*>(*j);
|
||||
assert(iface2);
|
||||
if (iface2->isUnnumbered()) continue;
|
||||
if (iface2->isUnprotected()) continue;
|
||||
if (iface->getId()==iface2->getId()) continue;
|
||||
if (iface->getOptionsObject()->getBool("cluster_interface") ||
|
||||
iface2->getOptionsObject()->getBool("cluster_interface")) continue;
|
||||
iface2->getOptionsObject()->getBool("cluster_interface"))
|
||||
continue;
|
||||
|
||||
if (iface->getSecurityLevel()==iface2->getSecurityLevel())
|
||||
{
|
||||
@ -339,6 +324,21 @@ string CompilerDriver_pix::run(const std::string &cluster_id,
|
||||
.arg(iface2->getLabel().c_str()).toStdString());
|
||||
throw FatalErrorInSingleRuleCompileMode();
|
||||
}
|
||||
|
||||
if (iface->getLabel()==iface2->getLabel())
|
||||
{
|
||||
QString err(
|
||||
"Label of each interface should be unique, "
|
||||
"however interfaces %1 (%2) and %3 (%4)"
|
||||
" have the same."
|
||||
);
|
||||
abort(fw, NULL, NULL,
|
||||
err.arg(iface->getName().c_str())
|
||||
.arg(iface->getLabel().c_str())
|
||||
.arg(iface2->getName().c_str())
|
||||
.arg(iface2->getLabel().c_str()).toStdString());
|
||||
throw FatalErrorInSingleRuleCompileMode();
|
||||
}
|
||||
}
|
||||
|
||||
// We only do limited checks for dedicated failover
|
||||
@ -347,11 +347,10 @@ string CompilerDriver_pix::run(const std::string &cluster_id,
|
||||
// commands.
|
||||
if (iface->isDedicatedFailover()) continue;
|
||||
|
||||
|
||||
/*
|
||||
* in PIX, we need network zones to be defined for all interfaces
|
||||
*/
|
||||
string netzone_id=iface->getStr("network_zone");
|
||||
string netzone_id = iface->getStr("network_zone");
|
||||
if (netzone_id=="")
|
||||
{
|
||||
QString err("Network zone definition is missing for interface %1 (%2)");
|
||||
@ -360,7 +359,8 @@ string CompilerDriver_pix::run(const std::string &cluster_id,
|
||||
.arg(iface->getLabel().c_str()).toStdString());
|
||||
throw FatalErrorInSingleRuleCompileMode();
|
||||
}
|
||||
FWObject *netzone=objdb->findInIndex(
|
||||
|
||||
FWObject *netzone = objdb->findInIndex(
|
||||
FWObjectDatabase::getIntId(netzone_id));
|
||||
if (netzone==NULL)
|
||||
{
|
||||
@ -447,13 +447,81 @@ string CompilerDriver_pix::run(const std::string &cluster_id,
|
||||
}
|
||||
}
|
||||
|
||||
/* Now that all checks are done, we can drop copies of cluster
|
||||
* interfaces that were added to the firewall by
|
||||
* CompilerDriver::populateClusterElements()
|
||||
*/
|
||||
list<FWObject*> copies_of_cluster_interfaces;
|
||||
for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i)
|
||||
{
|
||||
Interface *iface = Interface::cast(*i);
|
||||
assert(iface);
|
||||
|
||||
if (iface->getOptionsObject()->getBool("cluster_interface"))
|
||||
copies_of_cluster_interfaces.push_back(iface);
|
||||
}
|
||||
while (copies_of_cluster_interfaces.size())
|
||||
{
|
||||
fw->remove(copies_of_cluster_interfaces.front());
|
||||
copies_of_cluster_interfaces.pop_front();
|
||||
}
|
||||
|
||||
all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);
|
||||
|
||||
for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i)
|
||||
{
|
||||
Interface *iface = dynamic_cast<Interface*>(*i);
|
||||
assert(iface);
|
||||
/*
|
||||
* now sort interfaces by their network zone "width" (that is, more narrow
|
||||
* network zone should go first, interface with network zone "any" should be
|
||||
* the last)
|
||||
* missing labels on interfaces
|
||||
*
|
||||
std::sort(fw->begin(), fw->end(), sort_by_net_zone() );
|
||||
*/
|
||||
*/
|
||||
if (iface->getLabel()=="")
|
||||
{
|
||||
string lbl;
|
||||
if (iface->isDedicatedFailover())
|
||||
{
|
||||
// dedicated failover interface misses label. This
|
||||
// interface can be used in failover cluster group
|
||||
// or state sync group. Assign label depending on
|
||||
// the function.
|
||||
FWObjectTypedChildIterator it =
|
||||
cluster->findByType(StateSyncClusterGroup::TYPENAME);
|
||||
StateSyncClusterGroup *state_sync_group =
|
||||
StateSyncClusterGroup::cast(*it);
|
||||
if (state_sync_group && state_sync_group->hasMember(iface))
|
||||
lbl = "state";
|
||||
|
||||
if (!iface->getOptionsObject()->getStr("failover_group_id").empty())
|
||||
lbl = "failover";
|
||||
}
|
||||
|
||||
if (lbl.empty())
|
||||
{
|
||||
if (iface->getSecurityLevel()==0) lbl="outside";
|
||||
else
|
||||
{
|
||||
if (iface->getSecurityLevel()==100) lbl="inside";
|
||||
else
|
||||
{
|
||||
QString l("dmz%1");
|
||||
lbl = l.arg(iface->getSecurityLevel()).toStdString();
|
||||
}
|
||||
}
|
||||
}
|
||||
iface->setLabel(lbl);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
* now sort interfaces by their network zone "width" (that
|
||||
* is, more narrow network zone should go first, interface
|
||||
* with network zone "any" should be the last)
|
||||
*
|
||||
std::sort(fw->begin(), fw->end(), sort_by_net_zone() );
|
||||
*/
|
||||
|
||||
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb , fw, false));
|
||||
prep->compile();
|
||||
@ -661,9 +729,10 @@ void CompilerDriver_pix::pixClusterConfigurationChecks(Cluster *cluster,
|
||||
Interface *member_iface = Interface::cast(FWObjectReference::getObject(*it));
|
||||
assert(member_iface);
|
||||
|
||||
pixClusterGroupChecks(failover_group);
|
||||
|
||||
if (member_iface->isDedicatedFailover())
|
||||
{
|
||||
pixClusterGroupChecks(failover_group);
|
||||
failover_group_inspected = true;
|
||||
}
|
||||
}
|
||||
@ -709,10 +778,11 @@ void CompilerDriver_pix::pixClusterGroupChecks(ClusterGroup *cluster_group)
|
||||
}
|
||||
}
|
||||
|
||||
if (!member_iface->isDedicatedFailover())
|
||||
if (StateSyncClusterGroup::isA(cluster_group) &&
|
||||
!member_iface->isDedicatedFailover())
|
||||
{
|
||||
QString err("Interface %1 is used in a state synchronization or "
|
||||
"failover group but is not marked as 'Dedicated Failover' "
|
||||
QString err("Interface %1 is used in a state synchronization "
|
||||
"but is not marked as 'Dedicated Failover' "
|
||||
"interface. All interfaces used for the state "
|
||||
"synchronization or failover must be marked "
|
||||
"'Dedicated Failover'. ");
|
||||
@ -721,6 +791,7 @@ void CompilerDriver_pix::pixClusterGroupChecks(ClusterGroup *cluster_group)
|
||||
err.arg(member_iface->getName().c_str()).toStdString());
|
||||
throw FatalErrorInSingleRuleCompileMode();
|
||||
}
|
||||
|
||||
if (!member_iface->isRegular() || member_iface->countInetAddresses(true)==0)
|
||||
{
|
||||
QString err("Interface %1 which is used in state synchronization "
|
||||
|
||||
@ -696,7 +696,8 @@ void PolicyCompiler_pix::compile()
|
||||
add( new InterfacePolicyRules(
|
||||
"process interface policy rules and store interface ids"));
|
||||
|
||||
if ( fwopt->getBool("pix_assume_fw_part_of_any")) {
|
||||
if ( fwopt->getBool("pix_assume_fw_part_of_any"))
|
||||
{
|
||||
// add( new splitIfSrcAny( "split rule if src is any" ));
|
||||
add( new splitIfDstAny( "split rule if dst is any" ));
|
||||
}
|
||||
|
||||
@ -309,6 +309,7 @@ bool PolicyCompiler_pix::assignRuleToInterface_v6::processNext()
|
||||
{
|
||||
Interface *intf = Interface::cast(*i);
|
||||
if (intf->isUnprotected()) continue;
|
||||
if (intf->getOptionsObject()->getBool("cluster_interface")) continue;
|
||||
|
||||
PolicyRule *r = compiler->dbcopy->createPolicyRule();
|
||||
compiler->temp_ruleset->add(r);
|
||||
@ -347,14 +348,10 @@ bool PolicyCompiler_pix::pickACL_v6::processNext()
|
||||
PolicyRule *rule=getNext(); if (rule==NULL) return false;
|
||||
Interface *rule_iface = Interface::cast(compiler->dbcopy->findInIndex(rule->getInterfaceId()));
|
||||
if(rule_iface==NULL)
|
||||
{
|
||||
compiler->abort(
|
||||
|
||||
rule, "Missing interface assignment");
|
||||
}
|
||||
compiler->abort(rule, "Missing interface assignment");
|
||||
|
||||
string acl_name= rule_iface->getLabel() + "_acl_in";
|
||||
rule->setStr("acl",acl_name);
|
||||
rule->setStr("acl", acl_name);
|
||||
|
||||
ciscoACL *acl = new ciscoACL(acl_name, rule_iface, "in");
|
||||
pix_comp->acls[acl_name] = acl;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user