1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-22 03:07:20 +01:00
fwbuilder/src/cisco_lib/NamedObjectsAndGroupsSupport.cpp

362 lines
10 KiB
C++

/*
Firewall Builder
Copyright (C) 2010 NetCitadel, LLC
Author: Vadim Kurland vadim@vk.crocodile.org
$Id$
This program is free software which we release under the GNU General Public
License. You may redistribute and/or modify this program under the terms
of that license as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
To get a copy of the GNU General Public License, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "NamedObjectsAndGroupsSupport.h"
#include "NamedObject.h"
#include "ObjectGroupFactory.h"
#include "fwbuilder/FWObjectDatabase.h"
#include "fwbuilder/RuleElement.h"
#include "fwbuilder/IPService.h"
#include "fwbuilder/ICMPService.h"
#include "fwbuilder/TCPService.h"
#include "fwbuilder/UDPService.h"
#include "fwbuilder/CustomService.h"
#include "fwbuilder/Network.h"
#include "fwbuilder/Policy.h"
#include "fwbuilder/Interface.h"
#include "fwbuilder/Management.h"
#include "fwbuilder/Resources.h"
#include "fwbuilder/AddressTable.h"
#include "fwbuilder/AddressRange.h"
#include "fwbuilder/Firewall.h"
#include "fwcompiler/Compiler.h"
#include <iostream>
#include <algorithm>
#include <assert.h>
#include <QString>
#include <QStringList>
#include <QtDebug>
using namespace libfwbuilder;
using namespace fwcompiler;
using namespace std;
Group* NamedObjectManager::object_groups = NULL;
map<int, NamedObject*> NamedObjectManager::named_objects;
NamedObjectManager::NamedObjectManager(const libfwbuilder::Firewall *_fw)
{
fw = _fw;
BaseObjectGroup::name_disambiguation.clear();
NamedObject::name_disambiguation.clear();
}
NamedObjectManager::~NamedObjectManager()
{
std::map<int, NamedObject*>::iterator it1;
for (it1=named_objects.begin(); it1!=named_objects.end(); ++it1)
{
delete it1->second;
}
named_objects.clear();
}
void NamedObjectManager::addNamedObject(const FWObject *obj)
{
if (getNamedObject(obj) == NULL)
named_objects[obj->getId()] = new NamedObject(obj);
}
NamedObject* NamedObjectManager::getNamedObject(const FWObject *obj)
{
if (named_objects.count(obj->getId()) == 0) return NULL;
else
return named_objects[obj->getId()];
}
string NamedObjectManager::getNamedObjectsDefinitions()
{
QStringList output;
map<int, NamedObject*>::iterator it;
for (it=named_objects.begin(); it!=named_objects.end(); ++it)
{
NamedObject *nobj = it->second;
if (nobj==NULL) continue;
output << nobj->getCommand(fw);
}
output << "";
for (FWObject::iterator i=object_groups->begin(); i!=object_groups->end(); ++i)
{
BaseObjectGroup *og = dynamic_cast<BaseObjectGroup*>(*i);
assert(og!=NULL);
if (og->size()==0) continue;
output << "";
output << og->toString(this);
}
return output.join("\n").toUtf8().constData();
}
void NamedObjectManager::init(FWObjectDatabase *db)
{
object_groups = new Group();
db->add( object_groups );
// BaseObjectGroup::name_disambiguation.clear();
// NamedObject::name_disambiguation.clear();
}
CreateObjectGroups::~CreateObjectGroups()
{
}
BaseObjectGroup* CreateObjectGroups::findObjectGroup(RuleElement *re)
{
list<FWObject*> relement;
for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1)
relement.push_back(FWReference::getObject(*i1));
for (FWObject::iterator i=named_objects_manager->object_groups->begin();
i!=named_objects_manager->object_groups->end(); ++i)
{
BaseObjectGroup *og = dynamic_cast<BaseObjectGroup*>(*i);
assert(og!=NULL);
if (og->size()==0 || (og->size()!=re->size()) ) continue;
bool match = true;
for (FWObject::iterator i1=og->begin(); i1!=og->end(); ++i1)
{
if ( find(relement.begin(), relement.end(),
FWReference::getObject(*i1))==relement.end() )
{
match = false;
break;
}
}
if (match) return og;
}
return NULL;
}
bool CreateObjectGroups::processNext()
{
Rule *rule = prev_processor->getNextRule(); if (rule==NULL) return false;
string version = compiler->fw->getStr("version");
string platform = compiler->fw->getStr("platform");
Interface *rule_iface = Interface::cast(compiler->dbcopy->findInIndex(
rule->getInterfaceId()));
assert(rule_iface);
RuleElement *re = RuleElement::cast(rule->getFirstByType(re_type));
if (re->size()==1)
{
tmp_queue.push_back(rule);
return true;
}
BaseObjectGroup *obj_group = findObjectGroup(re);
if (obj_group==NULL)
{
obj_group = ObjectGroupFactory::createObjectGroup(compiler->fw);
named_objects_manager->object_groups->add(obj_group);
packObjects(re, obj_group);
obj_group->setObjectGroupTypeFromMembers(named_objects_manager);
QStringList group_name_prefix;
group_name_prefix.push_back(rule->getUniqueId().c_str());
group_name_prefix.push_back(name_suffix.c_str());
QString reg_name = BaseObjectGroup::registerGroupName(
group_name_prefix.join("."),
obj_group->getObjectGroupType());
obj_group->setName(reg_name.toUtf8().constData());
} else
{
re->clearChildren(false); //do not want to destroy children objects
re->addRef(obj_group);
}
tmp_queue.push_back(rule);
return true;
}
void CreateObjectGroups::packObjects(RuleElement *re, BaseObjectGroup *obj_group)
{
for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1)
{
FWObject *o = *i1;
FWObject *obj = o;
if (FWReference::cast(o)!=NULL)
obj = FWReference::cast(o)->getPointer();
obj_group->addRef(obj);
}
re->clearChildren(false); //do not want to destroy children objects
re->addRef(obj_group);
}
void CreateObjectGroupsForTSrc::packObjects(RuleElement *re,
BaseObjectGroup *obj_group)
{
if (libfwbuilder::XMLTools::version_compare(
compiler->fw->getStr("version"), "8.3")>=0)
{
// put all objects inside of the group, except for the interface
// if it belongs to the firewall
FWObject *re_interface = NULL;
for (FWObject::iterator i1=re->begin(); i1!=re->end(); ++i1)
{
FWObject *o = *i1;
FWObject *obj = o;
if (FWReference::cast(o)!=NULL)
obj = FWReference::cast(o)->getPointer();
if (Interface::isA(obj) && obj->isChildOf(compiler->fw))
{
re_interface = obj;
continue;
}
obj_group->addRef(obj);
}
re->clearChildren(false); //do not want to destroy children objects
if (re_interface)
{
// add interface back.
re->addRef(re_interface);
}
re->addRef(obj_group);
} else
{
CreateObjectGroups::packObjects(re, obj_group);
}
}
void createNamedObjectsCommon::printObjectsForRE(FWObject *re)
{
if (RuleElement::cast(re)!=NULL && RuleElement::cast(re)->isAny()) return;
for (FWObject::iterator it=re->begin(); it!=re->end(); ++it)
{
FWObject *obj = FWReference::getObject(*it);
if (Interface::isA(obj)) continue;
if (BaseObjectGroup::cast(obj)!=NULL) printObjectsForRE(obj);
else named_objects_manager->addNamedObject(obj);
}
}
/*
* We only need named objects for address ranges in policy. At least
* at this time, we have decided to not create named objects for
* everything and use them only in cases where it is inevitable.
*/
void createNamedObjectsForPolicy::printObjectsForRE(FWObject *re)
{
if (RuleElement::cast(re)!=NULL && RuleElement::cast(re)->isAny()) return;
for (FWObject::iterator it=re->begin(); it!=re->end(); ++it)
{
FWObject *obj = FWReference::getObject(*it);
if (Interface::isA(obj)) continue;
if (BaseObjectGroup::cast(obj)!=NULL) printObjectsForRE(obj);
if (AddressRange::isA(obj)) named_objects_manager->addNamedObject(obj);
}
}
/*
* We support named objects only for ASA 8.3 and in policy rules, only for
* address ranges.
*
* See #1962, it looks like ASA 8.3 does not support named objects or
* object-groups in place of port specification in access-list commands.
*/
bool createNamedObjectsForPolicy::processNext()
{
slurp();
if (tmp_queue.size()==0) return false;
for (deque<Rule*>::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k)
{
PolicyRule *policy_rule = PolicyRule::cast( *k );
if (policy_rule)
{
RuleElementSrc *src_re = policy_rule->getSrc(); assert(src_re);
printObjectsForRE(src_re);
RuleElementDst *dst_re = policy_rule->getDst(); assert(dst_re);
printObjectsForRE(dst_re);
//RuleElementSrv *srv_re = policy_rule->getSrv(); assert(srv_re);
//printObjectsForRE(srv_re);
}
}
return true;
}
bool createNamedObjectsForNAT::processNext()
{
slurp();
if (tmp_queue.size()==0) return false;
for (deque<Rule*>::iterator k=tmp_queue.begin(); k!=tmp_queue.end(); ++k)
{
NATRule *nat_rule = NATRule::cast( *k );
if (nat_rule)
{
RuleElementOSrc *osrc_re = nat_rule->getOSrc(); assert(osrc_re);
printObjectsForRE(osrc_re);
RuleElementODst *odst_re = nat_rule->getODst(); assert(odst_re);
printObjectsForRE(odst_re);
RuleElementOSrv *osrv_re = nat_rule->getOSrv(); assert(osrv_re);
printObjectsForRE(osrv_re);
RuleElementTSrc *tsrc_re = nat_rule->getTSrc(); assert(tsrc_re);
printObjectsForRE(tsrc_re);
RuleElementTDst *tdst_re = nat_rule->getTDst(); assert(tdst_re);
printObjectsForRE(tdst_re);
RuleElementTSrv *tsrv_re = nat_rule->getTSrv(); assert(tsrv_re);
printObjectsForRE(tsrv_re);
}
}
return true;
}