1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-19 09:47:20 +01:00

* NATCompiler_ipt.cpp (AssignInterface::processNext): fixes #1184

"compiler/GUI crash compiling cluster NAT rule when cluster and
members have dynamic interface". It should be possible to have
cluster interface that is mapped to dynamic interfaces of the
member firewalls and then use this interface or whole cluster
object in rules. Compiler should expand cluster object and replace
it with its interfaces and corresponding interfaces of the member
firewall and then correctly handle dynamic ones.
This commit is contained in:
Vadim Kurland 2010-02-01 00:42:35 +00:00
parent 0789f3c9b0
commit 945fa9191b
7 changed files with 166 additions and 89 deletions

View File

@ -1 +1 @@
#define BUILD_NUM 2470
#define BUILD_NUM 2477

View File

@ -1,18 +1,32 @@
2010-01-31 vadim <vadim@vk.crocodile.org>
* NATCompiler_ipt.cpp (AssignInterface::processNext): fixes #1184
"compiler/GUI crash compiling cluster NAT rule when cluster and
members have dynamic interface". It should be possible to have
cluster interface that is mapped to dynamic interfaces of the
member firewalls and then use this interface or whole cluster
object in rules. Compiler should expand cluster object and replace
it with its interfaces and corresponding interfaces of the member
firewall and then correctly handle dynamic ones.
2010-01-31 yalovoy <yalovoy@gmail.com>
* RuleSetModel.cpp: fixes #1182 rule number column is invisible when very
first rule is created in a rule set
* fixes #1164 focus moves in RuleSetView after paste
If i am in a rule and place the selection to service field of say rule 1
and ctrl c and then arrow down the selection to service element in rule 2
and ctrl v the focus then moves back to the rule number element of rule 2
after the paste instead of staying on the service element. likewise if i
am on an element and do ctrl x it brings the focus back to the rule number element.
* RuleSetModel.cpp: fixes #1182 rule number column is invisible
when very first rule is created in a rule set
my first expectation was that the focus would remain on the service element of
the rule and not brought back to the rule number element. i guess this has
something to do with refresh of the gui and you are not keeping track of which
element the selection was on for the last operation.
* fixes #1164 focus moves in RuleSetView after paste If i am in a
rule and place the selection to service field of say rule 1 and
ctrl c and then arrow down the selection to service element in
rule 2 and ctrl v the focus then moves back to the rule number
element of rule 2 after the paste instead of staying on the
service element. likewise if i am on an element and do ctrl x it
brings the focus back to the rule number element.
my first expectation was that the focus would remain on the
service element of the rule and not brought back to the rule
number element. i guess this has something to do with refresh of
the gui and you are not keeping track of which element the
selection was on for the last operation.
Affected files:
FWCmdRule.cpp

View File

@ -91,10 +91,11 @@ string PolicyCompiler_cisco::createRuleLabel(const string &txt,
string PolicyCompiler_cisco::debugPrintRule(Rule *r)
{
ostringstream str;
PolicyRule *rule=PolicyRule::cast(r);
PolicyRule *rule = PolicyRule::cast(r);
FWObject *rule_iface = dbcopy->findInIndex(rule->getInterfaceId());
string iname = (rule_iface!=NULL)?rule_iface->getName():"";
string dir= rule->getDirectionAsString();
string dir = rule->getDirectionAsString();
str << PolicyCompiler::debugPrintRule(rule) <<
" " << dir << " " << iname << " " << rule->getStr("acl") <<

View File

@ -1029,12 +1029,12 @@ void CompilerDriver::copyFailoverInterface(Cluster *cluster,
new_cl_if->getOptionsObject()->setBool("failover_master",
master_id == iface_str_id);
// cluster interface should "inherit" some of the
// attributes of the member interfaces it
// represents. For example, if member interfaces are
// marked "unprotected" or "dedicated failover", so
// should be the cluster interface. What else?
/*
* cluster interface should "inherit" some of the attributes of
* the member interfaces it represents. For example, if member
* interfaces are marked "unprotected" or "dedicated failover",
* should be the cluster interface. What else?
*/
new_cl_if->setDedicatedFailover(iface->isDedicatedFailover());
new_cl_if->setUnprotected(iface->isUnprotected());
@ -1043,8 +1043,35 @@ void CompilerDriver::copyFailoverInterface(Cluster *cluster,
/* Add copy of firewall's real interface to the cluster to make sure
* compiler recognizes it when it encounters cluster object in rules.
* This fixes #15 (makes compiler choose correct chains)
*
* Update 01/31/2010:
*
* Example of rule where this is necessary is anti-spoofing
* rule. When cluster object is placed in rule element, it is
* assumed that it represents its own addresses, plus addresses of
* the members.
*
* A copy of the member interface does not have
* FailoverClusterGroup child object and is not recognized as
* failover interface. This is important when this interface is
* dynamic. When cluster object is used in the rule and then
* replaced with all its interfaces in one of the rule processors,
* this copy interface appears as having cluster as a parent, not
* the firewall that is being compiled. This creates problems with
* processing of dynamic interfaces. They look like they belong to
* some other object and trigger "can use dynamic interface
* because its address is unknown" error.
*
* However there is no need to add a copy of the interface of the
* member to the cluster if this interface is dynamic or
* unnumbered. Corresponding cluster interface inherits isDyn()
* property and is sufficient. This is for ticket #1184
*/
cluster->addCopyOf(iface, true);
if ( ! iface->isDyn() && ! iface->isUnnumbered())
{
FWObject *new_member_if = cluster->addCopyOf(iface, true);
new_member_if->setBool("member_interface_copy", true);
}
}
/**

View File

@ -56,6 +56,7 @@
#include <QString>
#include <QRegExp>
#include <QtDebug>
#include <algorithm>
#include <functional>
@ -162,6 +163,12 @@ string NATCompiler_ipt::debugPrintRule(Rule *r)
{
NATRule *rule = NATRule::cast(r);
string iface_name = rule->getInterfaceStr();
if (iface_name.empty())
{
int iface_id = rule->getInterfaceId();
FWObject *iface = dbcopy->findInIndex(iface_id);
if (iface) iface_name = iface->getName();
}
return NATCompiler::debugPrintRule(rule)+
" " + FWObjectDatabase::getStringId(rule->getInterfaceId()) +
@ -821,6 +828,12 @@ bool NATCompiler_ipt::addVirtualAddress::processNext()
tmp_queue.push_back(rule);
bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member");
Cluster *cluster = NULL;
if (cluster_member)
cluster = Cluster::cast(
compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id")));
Address *a=NULL;
if (rule->getRuleType()==NATRule::SNAT || rule->getRuleType()==NATRule::DNAT)
@ -834,8 +847,10 @@ bool NATCompiler_ipt::addVirtualAddress::processNext()
// addresses for NAT is not supported with address ranges,
// regardless of the result of complexMatch()
if ( ! a->isAny() && ! compiler->complexMatch(a,compiler->fw) &&
options->getBool("manage_virtual_addr") )
if ( ! a->isAny() &&
! compiler->complexMatch(a, compiler->fw) &&
! compiler->complexMatch(a, cluster) &&
options->getBool("manage_virtual_addr"))
{
if (AddressRange::cast(a)!=NULL)
{
@ -1230,6 +1245,11 @@ void NATCompiler_ipt::checkForDynamicInterfacesOfOtherObjects::findDynamicInterf
{
if (re->isAny()) return;
bool cluster_member = compiler->fw->getOptionsObject()->getBool("cluster_member");
FWObject *cluster = NULL;
if (cluster_member)
cluster = compiler->dbcopy->findInIndex(compiler->fw->getInt("parent_cluster_id"));
list<FWObject*> cl;
for (list<FWObject*>::iterator i1=re->begin(); i1!=re->end(); ++i1)
{
@ -1238,17 +1258,22 @@ void NATCompiler_ipt::checkForDynamicInterfacesOfOtherObjects::findDynamicInterf
if (FWReference::cast(o)!=NULL) obj=FWReference::cast(o)->getPointer();
Interface *ifs =Interface::cast( obj );
if (ifs!=NULL && ifs->isDyn() && ! ifs->isChildOf(compiler->fw))
if (ifs!=NULL && ifs->isDyn() &&
! ifs->isChildOf(compiler->fw) &&
! ifs->isChildOf(cluster))
{
#if 0
cerr << endl;
cerr << "NATCompiler_ipt::checkForDynamicInterfacesOfOtherObjects" << endl;
cerr << "ifs: " << endl;
ifs->dump(true,true);
cerr << endl;
cerr << "fw: " << endl;
compiler->fw->dump(true,true);
cerr << endl;
cerr << " ifs=" << ifs << " " << ifs->getName().c_str()
<< " parent=" << ifs->getParent()
<< " " << ifs->getParent()->getName().c_str()
<< " dyn=" << ifs->isDyn()
<< endl;
cerr << "compiler->fw=" << compiler->fw
<< " " << compiler->fw->getName().c_str() << endl;
#endif
char errstr[2048];
sprintf(errstr, "Can not build rule using dynamic interface '%s' "
"of the object '%s' because its address in unknown.",
@ -2242,29 +2267,37 @@ bool NATCompiler_ipt::AssignInterface::processNext()
if (iface)
{
if (Cluster::isA(iface->getParentHost()) &&
iface->isFailoverInterface())
if (Cluster::isA(iface->getParentHost()))
{
FWObject *failover_group =
iface->getFirstByType(FailoverClusterGroup::TYPENAME);
if (failover_group)
if (iface->isFailoverInterface())
{
for (FWObjectTypedChildIterator it =
failover_group->findByType(FWObjectReference::TYPENAME);
it != it.end(); ++it)
{
Interface *fw_iface = Interface::cast(FWObjectReference::getObject(*it));
assert(fw_iface);
if (fw_iface->isChildOf(compiler->fw))
FailoverClusterGroup *failover_group =
FailoverClusterGroup::cast(
iface->getFirstByType(FailoverClusterGroup::TYPENAME));
Interface *fw_iface =
failover_group->getInterfaceForMemberFirewall(compiler->fw);
if (fw_iface)
{
// this is a bit tricky: we assign rule to the
// member firewall's inteface but TSrc remains
// cluster interface or its address.
iface = fw_iface;
rule->setInterfaceId(iface->getId());
tmp_queue.push_back(rule);
return true;
}
} else
{
// parent is the cluster but there is no failover
// group. This must be a copy of the member interface.
rule->setInterfaceId(iface->getId());
tmp_queue.push_back(rule);
return true;
}
}
} else
{
if (iface->isChildOf(compiler->fw))
@ -2276,6 +2309,14 @@ bool NATCompiler_ipt::AssignInterface::processNext()
}
}
#if 0
FWObject *p = iface->getParent();
qDebug() << "Checkpoint #1"
<< " iface=" << iface << " " << iface->getName().c_str()
<< " parent=" << p << " " << p->getName().c_str()
<< " " << p->getTypeName().c_str();
#endif
/* if we appear here, then TSrc is not an interface or address of an
* interface. This processor will simply pass a rule along if firewall
* has no interfaces at all. I wonder if I really have to do this,

View File

@ -4049,30 +4049,12 @@ bool PolicyCompiler_ipt::checkInterfaceAgainstAddressFamily::processNext()
* for ticket #1172 : this is cluster interface that has no
* address, check properties of the corresponding member
*/
FWObject *failover_group =
rule_iface->getFirstByType(FailoverClusterGroup::TYPENAME);
FailoverClusterGroup *fg = FailoverClusterGroup::cast(
rule_iface->getFirstByType(FailoverClusterGroup::TYPENAME));
Interface *other_iface = fg->getInterfaceForMemberFirewall(compiler->fw);
for (FWObjectTypedChildIterator it =
failover_group->findByType(FWObjectReference::TYPENAME);
it != it.end(); ++it)
if (other_iface == NULL)
{
Interface *other_iface =
Interface::cast(FWObjectReference::getObject(*it));
assert(other_iface);
if (other_iface->isChildOf(compiler->fw))
{
if (other_iface->getByType(addr_type).size() != 0)
{
tmp_queue.push_back(rule);
return true;
} else
{
// member interface also has no addresses
return true;
}
}
}
// if we get here, this cluster interface does not have
// any corresponding interface of the firewall we are
// compiling right now. What is the right thing to do in
@ -4089,6 +4071,17 @@ bool PolicyCompiler_ipt::checkInterfaceAgainstAddressFamily::processNext()
return true;
}
if (other_iface->getByType(addr_type).size() != 0)
{
tmp_queue.push_back(rule);
return true;
} else
{
// member interface also has no addresses
return true;
}
}
// interface has no addresses and is not cluster failover interface
// drop the rule
return true;

View File

@ -662,7 +662,7 @@
</Library>
<Library id="id1495X69605" color="#d2ffd0" name="User" comment="" ro="False">
<ObjectGroup id="id1502X69605" name="Clusters" comment="" ro="False">
<Cluster id="id2366X75741" host_OS="secuwall" inactive="True" lastCompiled="1248670597" lastInstalled="0" lastModified="1251419063" platform="iptables" name="cluster1" comment="" ro="False">
<Cluster id="id2366X75741" host_OS="secuwall" inactive="True" lastCompiled="1248670597" lastInstalled="0" lastModified="1264977121" platform="iptables" name="cluster1" comment="" ro="False">
<NAT id="id2370X75741" name="NAT" comment="" ro="False" ipv4_rule_set="False" ipv6_rule_set="False" top_rule_set="True">
<NATRule id="id4606X78273" disabled="False" position="0" action="Translate" comment="">
<OSrc neg="False">
@ -841,9 +841,10 @@
<Option name="iface_mtu">1500</Option>
<Option name="type">vrrp</Option>
</InterfaceOptions>
<FailoverClusterGroup id="id2382X75741" master_iface="id2844X69605" type="vrrp" name="cluster1:vrrp1:members" comment="">
<ObjectRef ref="id2844X69605"/>
<ObjectRef ref="id3118X69605"/>
<FailoverClusterGroup id="id2382X75741" master_iface="id4033X2906" type="vrrp" name="cluster1:vrrp1:members" comment="">
<ObjectRef ref="id4033X2906"/>
<ObjectRef ref="id4058X2906"/>
<ClusterGroupOptions/>
</FailoverClusterGroup>
</Interface>
<Interface id="id3213X42281" dedicated_failover="False" dyn="False" security_level="0" unnum="False" unprotected="False" name="vrrp2" comment="" ro="False">