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:
parent
0789f3c9b0
commit
945fa9191b
@ -1,24 +1,38 @@
|
||||
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
|
||||
FWCmdRule.h
|
||||
RuleSetView.cpp
|
||||
RuleSetView.h
|
||||
RuleSetView.h
|
||||
|
||||
2010-01-30 vadim <vadim@vk.crocodile.org>
|
||||
|
||||
|
||||
@ -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") <<
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QRegExp>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
@ -161,7 +162,13 @@ string NATCompiler_ipt::getNewTmpChainName(NATRule *rule)
|
||||
string NATCompiler_ipt::debugPrintRule(Rule *r)
|
||||
{
|
||||
NATRule *rule = NATRule::cast(r);
|
||||
string iface_name = rule->getInterfaceStr();
|
||||
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)
|
||||
FailoverClusterGroup *failover_group =
|
||||
FailoverClusterGroup::cast(
|
||||
iface->getFirstByType(FailoverClusterGroup::TYPENAME));
|
||||
|
||||
Interface *fw_iface =
|
||||
failover_group->getInterfaceForMemberFirewall(compiler->fw);
|
||||
|
||||
if (fw_iface)
|
||||
{
|
||||
Interface *fw_iface = Interface::cast(FWObjectReference::getObject(*it));
|
||||
assert(fw_iface);
|
||||
if (fw_iface->isChildOf(compiler->fw))
|
||||
{
|
||||
iface = fw_iface;
|
||||
rule->setInterfaceId(iface->getId());
|
||||
tmp_queue.push_back(rule);
|
||||
return true;
|
||||
}
|
||||
// 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,
|
||||
|
||||
@ -4049,44 +4049,37 @@ 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
|
||||
// this case? I suppose we can't check if this interface
|
||||
// matches address family. Dropping the rule.
|
||||
QString err("Cluster interface '%1' does not map onto any "
|
||||
"interface of the firewall '%2' but is used "
|
||||
"in the 'Interface' rule element. "
|
||||
"The rule will be dropped because it can "
|
||||
"not be associated with this interface.");
|
||||
compiler->warning(rule,
|
||||
err.arg(rule_iface->getName().c_str())
|
||||
.arg(compiler->fw->getName().c_str()).toStdString());
|
||||
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;
|
||||
}
|
||||
// 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
|
||||
// this case? I suppose we can't check if this interface
|
||||
// matches address family. Dropping the rule.
|
||||
QString err("Cluster interface '%1' does not map onto any "
|
||||
"interface of the firewall '%2' but is used "
|
||||
"in the 'Interface' rule element. "
|
||||
"The rule will be dropped because it can "
|
||||
"not be associated with this interface.");
|
||||
compiler->warning(rule,
|
||||
err.arg(rule_iface->getName().c_str())
|
||||
.arg(compiler->fw->getName().c_str()).toStdString());
|
||||
return true;
|
||||
}
|
||||
|
||||
// interface has no addresses and is not cluster failover interface
|
||||
|
||||
@ -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">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user