mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-03-25 04:37:22 +01:00
3099 lines
91 KiB
C++
3099 lines
91 KiB
C++
/*
|
|
|
|
Firewall Builder
|
|
|
|
Copyright (C) 2003 NetCitadel, LLC
|
|
|
|
Author: Vadim Kurland vadim@fwbuilder.org
|
|
|
|
$Id: ObjectManipulator.cpp,v 1.164 2007/07/07 05:39:34 vkurland Exp $
|
|
|
|
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 "fwbuilder_ph.h"
|
|
|
|
#include "config.h"
|
|
#include "global.h"
|
|
#include "utils.h"
|
|
#include "utils_no_qt.h"
|
|
|
|
#include "ObjectManipulator.h"
|
|
#include "ObjectEditor.h"
|
|
#include "ObjectTreeViewItem.h"
|
|
#include "ObjectTreeView.h"
|
|
#include "FWObjectClipboard.h"
|
|
#include "FWObjectPropertiesFactory.h"
|
|
#include "FWBSettings.h"
|
|
#include "listOfLibraries.h"
|
|
#include "newFirewallDialog.h"
|
|
#include "newHostDialog.h"
|
|
#include "findDialog.h"
|
|
#include "newGroupDialog.h"
|
|
#include "FindObjectWidget.h"
|
|
|
|
#include <QTextEdit>
|
|
#include <QTime>
|
|
#include <qobject.h>
|
|
#include <qobject.h>
|
|
#include <qimage.h>
|
|
#include <qpixmapcache.h>
|
|
#include <qheaderview.h>
|
|
#include <QStackedWidget>
|
|
#include <qpushbutton.h>
|
|
#include <qtabwidget.h>
|
|
#include <qaction.h>
|
|
#include <qlabel.h>
|
|
#include <qcombobox.h>
|
|
#include <qsplitter.h>
|
|
#include <qtoolbutton.h>
|
|
#include <qlayout.h>
|
|
#include <qmessagebox.h>
|
|
#include <qmenu.h>
|
|
#include <qapplication.h>
|
|
#include <qcursor.h>
|
|
#include <qtooltip.h>
|
|
#include <qlineedit.h>
|
|
#include <qcombobox.h>
|
|
#include <qstatusbar.h>
|
|
#include <qeventloop.h>
|
|
#include <QPixmap>
|
|
|
|
|
|
#include "DialogFactory.h"
|
|
#include "FWBTree.h"
|
|
#include "FWWindow.h"
|
|
#include "ProjectPanel.h"
|
|
#include "ConfirmDeleteObjectDialog.h"
|
|
|
|
#include "fwbuilder/Library.h"
|
|
#include "fwbuilder/Firewall.h"
|
|
#include "fwbuilder/Host.h"
|
|
#include "fwbuilder/Network.h"
|
|
#include "fwbuilder/IPv4.h"
|
|
#include "fwbuilder/DNSName.h"
|
|
#include "fwbuilder/AddressTable.h"
|
|
#include "fwbuilder/AddressRange.h"
|
|
#include "fwbuilder/ObjectGroup.h"
|
|
|
|
#include "fwbuilder/Resources.h"
|
|
#include "fwbuilder/FWReference.h"
|
|
#include "fwbuilder/Interface.h"
|
|
#include "fwbuilder/RuleSet.h"
|
|
#include "fwbuilder/RuleElement.h"
|
|
|
|
#ifdef USE_INTERFACE_POLICY
|
|
# include "fwbuilder/InterfacePolicy.h"
|
|
#endif
|
|
|
|
#include "fwbuilder/CustomService.h"
|
|
#include "fwbuilder/IPService.h"
|
|
#include "fwbuilder/ICMPService.h"
|
|
#include "fwbuilder/TCPService.h"
|
|
#include "fwbuilder/UDPService.h"
|
|
#include "fwbuilder/ServiceGroup.h"
|
|
#include "fwbuilder/TagService.h"
|
|
|
|
#include "fwbuilder/Interval.h"
|
|
#include "fwbuilder/IntervalGroup.h"
|
|
#include "fwbuilder/Management.h"
|
|
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include "AskLibForCopyDialog.h"
|
|
|
|
using namespace std;
|
|
using namespace libfwbuilder;
|
|
|
|
#define OBJTREEVIEW_WIDGET_NAME "ObjTreeView"
|
|
|
|
|
|
HistoryItem::~HistoryItem() {}
|
|
|
|
ObjectManipulator::~ObjectManipulator()
|
|
{
|
|
delete m_objectManipulator;
|
|
}
|
|
|
|
ObjectManipulator::ObjectManipulator( QWidget *parent):
|
|
QWidget(parent), currentObj(0), current_tree_view(0)
|
|
{
|
|
m_objectManipulator = new Ui::ObjectManipulator_q;
|
|
m_objectManipulator->setupUi(this);
|
|
setObjectName(tr("Object Manipulator"));
|
|
QObject* par = parent;
|
|
while(! (m_project = dynamic_cast<ProjectPanel*>(par)))
|
|
{
|
|
par = par->parent();
|
|
}
|
|
|
|
treeWidth = -1;
|
|
treeHeight = -1;
|
|
currentObj = NULL;
|
|
active = false;
|
|
current_tree_view=NULL;
|
|
|
|
// setFocusPolicy( QWidget::StrongFocus );
|
|
|
|
/* Adding pop-down menu to the button "New" */
|
|
|
|
QString icon_path=":/Icons/";
|
|
|
|
QMenu* newObjectPopup = new QMenu( this );
|
|
|
|
newObjectPopup->addAction(QIcon(icon_path+Library::TYPENAME+"/icon-tree"), tr( "New &Library" ), this, SLOT( newLibrary() ));
|
|
|
|
newObjectPopup->addSeparator();
|
|
|
|
newObjectPopup->addAction(QIcon(icon_path+Firewall::TYPENAME+"/icon-tree"), tr( "New &Firewall" ), this, SLOT( newFirewall() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+Host::TYPENAME+"/icon-tree"), tr( "New &Host" ), this, SLOT( newHost() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+Interface::TYPENAME+"/icon-tree"), tr( "New &Interface" ), this, SLOT( newInterface() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+Network::TYPENAME+"/icon-tree"), tr( "New &Network" ), this, SLOT( newNetwork() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+IPv4::TYPENAME+"/icon-tree"), tr( "New &Address" ), this, SLOT( newAddress() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+DNSName::TYPENAME+"/icon-tree"), tr( "New &DNS Name" ), this, SLOT( newDNSName() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+AddressTable::TYPENAME+"/icon-tree"), tr( "New A&ddress Table" ), this, SLOT( newAddressTable() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+AddressRange::TYPENAME+"/icon-tree"), tr( "New Address &Range" ), this, SLOT( newAddressRange() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+ObjectGroup::TYPENAME+"/icon-tree"), tr( "New &Object Group" ), this, SLOT( newObjectGroup() ));
|
|
newObjectPopup->addSeparator();
|
|
newObjectPopup->addAction(QIcon(icon_path+CustomService::TYPENAME+"/icon-tree"), tr( "New &Custom Service" ), this, SLOT( newCustom() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+IPService::TYPENAME+"/icon-tree"), tr( "New &IP Service" ), this, SLOT( newIP() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+ICMPService::TYPENAME+"/icon-tree"), tr( "New IC&MP Service" ), this, SLOT( newICMP() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+TCPService::TYPENAME+"/icon-tree"), tr( "New &TCP Serivce" ), this, SLOT( newTCP() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+UDPService::TYPENAME+"/icon-tree"), tr( "New &UDP Service" ), this, SLOT( newUDP() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+TagService::TYPENAME+"/icon-tree"), tr( "New &TagService" ), this, SLOT( newTagService() ));
|
|
newObjectPopup->addAction(QIcon(icon_path+ServiceGroup::TYPENAME+"/icon-tree"), tr( "New &Service Group" ), this, SLOT( newServiceGroup() ));
|
|
newObjectPopup->addSeparator();
|
|
newObjectPopup->addAction(QIcon(icon_path+Interval::TYPENAME+"/icon-tree"), tr( "New Ti&me Interval" ), this, SLOT( newInterval() ));
|
|
|
|
// QToolButton *btn = (QToolButton*)toolBar->child("newObjectAction_action_button");
|
|
|
|
m_objectManipulator->newButton->setMenu( newObjectPopup );
|
|
|
|
#if defined(Q_WS_X11)
|
|
/* do something that makes sense only on X11 */
|
|
|
|
#elif defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
|
|
/* do something that only works on windows */
|
|
|
|
#elif defined(Q_OS_MAC)
|
|
|
|
#endif
|
|
|
|
// backwardAction->setEnabled( false );
|
|
|
|
// setMinimumSize( QSize( 0, 174 ) );
|
|
// splitter3->setMinimumSize( QSize( 0, 118 ) );
|
|
// treeFrame->setMinimumSize( QSize( 200, 0 ) );
|
|
// splitter3->setResizeMode( treeFrame, QSplitter::KeepSize );
|
|
}
|
|
|
|
|
|
QString ObjectManipulator::getTreeLabel( FWObject *obj )
|
|
{
|
|
QString name;
|
|
|
|
if (Interface::isA(obj))
|
|
{
|
|
name=Interface::constcast(obj)->getLabel().c_str();
|
|
if (name=="") name=QString::fromUtf8(obj->getName().c_str());
|
|
QString q;
|
|
if (Interface::constcast(obj)->isDyn()) q=" dyn";
|
|
if (Interface::constcast(obj)->isUnnumbered()) q=" unnum";
|
|
if (Interface::constcast(obj)->isBridgePort()) q=" bridge port";
|
|
if (Interface::constcast(obj)->isExt()) q=q+" ext";
|
|
if (Interface::constcast(obj)->isUnprotected())q=q+" unp";
|
|
if (q!="") name=name+" ("+q+")";
|
|
}
|
|
else
|
|
{
|
|
name=QString::fromUtf8(obj->getName().c_str());
|
|
if (Library::isA(obj) && obj->isReadOnly())
|
|
name=name+QObject::tr(" ( read only )");
|
|
}
|
|
|
|
#if 0
|
|
if (name=="")
|
|
{ // no name, use type description string instead
|
|
name= Resources::global_res->getObjResourceStr(obj,"description").c_str();
|
|
}
|
|
#endif
|
|
return name;
|
|
}
|
|
|
|
ObjectTreeViewItem* ObjectManipulator::insertObject( ObjectTreeViewItem *itm,
|
|
FWObject *obj )
|
|
{
|
|
if (FWReference::cast(obj)!=NULL) return NULL;
|
|
if (Resources::global_res->getObjResourceBool(obj,"hidden") ) return NULL;
|
|
if (RuleSet::cast(obj)!=NULL) return NULL;
|
|
|
|
ObjectTreeViewItem *nitm=NULL;
|
|
|
|
QString icn_filename;
|
|
|
|
if (m_project->isSystem(obj)) icn_filename=":/Icons/folder1.png";
|
|
else
|
|
icn_filename=(":/Icons/"+obj->getTypeName()+"/icon-tree").c_str();
|
|
//icn_filename=Resources::global_res->getObjResourceStr(obj, "icon-tree").c_str();
|
|
|
|
if (obj->getBool("ro")) icn_filename = ":/Icons/lock.png";
|
|
|
|
if (Resources::global_res->getResourceBool(
|
|
string("/FWBuilderResources/Type/") +
|
|
obj->getTypeName() + "/hidden") ) return NULL;
|
|
|
|
nitm=new ObjectTreeViewItem( itm );
|
|
nitm->setLib("");
|
|
nitm->setText( 0, getTreeLabel(obj) );
|
|
QPixmap pm;
|
|
if ( ! QPixmapCache::find( icn_filename, pm) )
|
|
{
|
|
pm.load( icn_filename );
|
|
QPixmapCache::insert( icn_filename, pm);
|
|
}
|
|
nitm->setIcon( 0, QIcon(pm) );
|
|
nitm->setIcon( 1, QIcon(pm) );
|
|
nitm->setFlags(nitm->flags() | Qt::ItemIsDragEnabled);
|
|
|
|
nitm->setProperty("id", obj->getId().c_str() );
|
|
nitm->setProperty("type", obj->getTypeName().c_str() );
|
|
nitm->setFWObject( obj );
|
|
|
|
allItems[obj] = nitm;
|
|
|
|
return nitm;
|
|
}
|
|
|
|
|
|
void ObjectManipulator::insertSubtree( ObjectTreeViewItem *itm,
|
|
FWObject *obj )
|
|
{
|
|
ObjectTreeViewItem *nitm = insertObject(itm, obj);
|
|
|
|
if (nitm==NULL) return;
|
|
if ( m_project->isSystem(obj) ) nitm->setExpanded( st->getExpandTree() );
|
|
|
|
for (list<FWObject*>::iterator m=obj->begin(); m!=obj->end(); m++)
|
|
{
|
|
FWObject *o1=*m;
|
|
if (FWReference::cast(o1)!=NULL) continue;
|
|
insertSubtree( nitm, o1 );
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::showDeletedObjects(bool f)
|
|
{
|
|
try
|
|
{
|
|
FWObject *dobj = m_project->db()->findInIndex( FWObjectDatabase::getDeletedObjectsId());
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::showDeletedObjects f=%d dobj=%p",f, dobj);
|
|
|
|
if (dobj==NULL)
|
|
{
|
|
dobj=m_project->db()->create(Library::TYPENAME);
|
|
dobj->setId(m_project->db()->getDeletedObjectsId());
|
|
dobj->setName("Deleted Objects");
|
|
dobj->setReadOnly(false);
|
|
m_project->db()->add(dobj);
|
|
}
|
|
|
|
int idx = getIdxForLib(dobj);
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::showDeletedObjects idx=%d",idx);
|
|
|
|
if (f)
|
|
{
|
|
if (idx>=0) return;
|
|
addTreePage( dobj );
|
|
openLib( dobj );
|
|
} else
|
|
{
|
|
if (idx<0) return;
|
|
|
|
QTreeWidget *otv = idxToTrees[idx];
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::showDeletedObjects otv=%p",otv);
|
|
|
|
assert(otv!=NULL);
|
|
m_objectManipulator->widgetStack->removeWidget( otv );
|
|
removeLib(idx);
|
|
}
|
|
}
|
|
catch(FWException &ex)
|
|
{
|
|
/* we get exception if file is opened read-only and there is no "deleted
|
|
* objects" library yet
|
|
*/
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::removeObjectFromTreeView(FWObject *obj )
|
|
{
|
|
QTreeWidget *objTreeView = idxToTrees[ getIdxForLib(getCurrentLib()) ];
|
|
dynamic_cast<ObjectTreeView*>(objTreeView)->clearLastSelected();
|
|
|
|
ObjectTreeViewItem *itm = allItems[obj];
|
|
allItems[obj]=NULL;
|
|
// allItems.erase(obj);
|
|
|
|
itm->parent()->takeChild( itm->parent()->indexOfChild(itm) );
|
|
delete itm;
|
|
}
|
|
|
|
void ObjectManipulator::updateLibColor(FWObject *lib)
|
|
{
|
|
QTreeWidget *objTreeView = idxToTrees[ getIdxForLib(lib) ];
|
|
|
|
QString clr=lib->getStr("color").c_str();
|
|
if (clr=="" || clr=="#000000" || clr=="black") clr="#FFFFFF";
|
|
|
|
QPalette palette = objTreeView->palette();
|
|
palette.setColor(QPalette::Active, QPalette::Base, QColor( clr ));
|
|
objTreeView->setPalette(palette);
|
|
}
|
|
|
|
int ObjectManipulator::getIdxForLib(FWObject* lib)
|
|
{
|
|
for (int i=0; i<m_objectManipulator->libs->count(); i++)
|
|
if ( idxToLibs[i]->getId() == lib->getId() ) return i;
|
|
|
|
return -1;
|
|
}
|
|
|
|
void ObjectManipulator::updateLibName(FWObject *lib)
|
|
{
|
|
int oldidx = getIdxForLib(lib);
|
|
QTreeWidget *objTreeView = idxToTrees[oldidx];
|
|
QString newlibname = QString::fromUtf8(lib->getName().c_str());
|
|
|
|
if (m_objectManipulator->libs->itemText(oldidx)!=newlibname)
|
|
{
|
|
removeLib(oldidx);
|
|
// libs->removeItem( oldidx );
|
|
// idxToLibs.erase(oldidx);
|
|
// idxToTrees.erase(oldidx);
|
|
|
|
addLib(lib,objTreeView);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* TODO: make this signal/slot. Dialogs just emit signal
|
|
* 'updateObject_sign', which objectManipulator should have connected
|
|
* to its slot which would do what updateObjName does now, and more.
|
|
*/
|
|
void ObjectManipulator::updateObjName(FWObject *obj,
|
|
const QString &oldName,
|
|
bool askForAutorename)
|
|
{
|
|
info(); // need to update info in case user edited comments and other attributes.
|
|
|
|
if (oldName == obj->getName().c_str()) return;
|
|
|
|
if (obj!=currentObj) openObject(obj);
|
|
|
|
QTreeWidgetItem *itm = allItems[obj];
|
|
assert(itm!=NULL);
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("ObjectManipulator::updateObjName changing name %s -> %s",
|
|
oldName.toLatin1().constData(), QString::fromUtf8(obj->getName().c_str()).toLatin1().constData());
|
|
}
|
|
|
|
if ((QString::fromUtf8(obj->getName().c_str())!=oldName) &&
|
|
(Host::isA(obj) || Firewall::isA(obj) || Interface::isA(obj)))
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::updateObjName autorename");
|
|
autorename(obj,askForAutorename);
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::updateObjName autorename done");
|
|
}
|
|
|
|
itm->setText(0, getTreeLabel( obj ) );
|
|
|
|
if (!Library::isA(obj)) itm->parent()->sortChildren(0, Qt::AscendingOrder);
|
|
|
|
/* need to update name of the firewall in the drop-down list */
|
|
if (Firewall::isA(obj))
|
|
{
|
|
m_project->updateFirewallName(obj,oldName);
|
|
}
|
|
|
|
// reopenFirewalls is called from FirewallDialog::applyChanges()
|
|
//if (QString::fromUtf8(obj->getName().c_str())!=oldName)
|
|
//{
|
|
// QTimer::singleShot( 0, m_project, SLOT(reopenFirewall()) );
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
* variant specifically used for interfaces that have name and a label
|
|
*/
|
|
void ObjectManipulator::updateObjName(FWObject *obj,
|
|
const QString &oldName,
|
|
const QString &oldLabel,
|
|
bool askForAutorename)
|
|
{
|
|
if (obj!=currentObj) openObject(obj);
|
|
|
|
QTreeWidgetItem *itm = allItems[obj];
|
|
assert(itm!=NULL);
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("ObjectManipulator::updateObjName changing name %s -> %s",
|
|
oldName.toLatin1().constData(), QString::fromUtf8(obj->getName().c_str()).toLatin1().constData());
|
|
}
|
|
|
|
if ((QString::fromUtf8(obj->getName().c_str())!=oldName) && Interface::isA(obj))
|
|
autorename(obj,askForAutorename);
|
|
|
|
itm->setText(0, getTreeLabel( obj ) );
|
|
itm->parent()->sortChildren(0, Qt::AscendingOrder);//();
|
|
|
|
Interface *i = Interface::cast(obj);
|
|
if ((i!=NULL && i->getLabel()!=oldLabel.toLatin1().constData()) ||
|
|
(QString::fromUtf8(obj->getName().c_str())!=oldName))
|
|
{
|
|
//m_project->reopenFirewall();
|
|
m_project->scheduleRuleSetRedraw();
|
|
}
|
|
|
|
info(); // need to update info in case user edited comments and other attributes.
|
|
}
|
|
|
|
void ObjectManipulator::autorename(FWObject *obj,bool ask)
|
|
{
|
|
if (Host::isA(obj) || Firewall::isA(obj))
|
|
{
|
|
if (!ask || QMessageBox::warning(
|
|
this,"Firewall Builder",
|
|
tr(
|
|
"The name of the object '%1' has changed. The program can also\n"
|
|
"rename IP address objects that belong to this object,\n"
|
|
"using standard naming scheme 'host_name:interface_name:ip'.\n"
|
|
"This makes it easier to distinguish what host or a firewall\n"
|
|
"given IP address object belongs to when it is used in \n"
|
|
"the policy or NAT rule. The program also renames MAC address\n"
|
|
"objects using scheme 'host_name:interface_name:mac'.\n"
|
|
"Do you want to rename child IP and MAC address objects now?\n"
|
|
"(If you click 'No', names of all address objects that belong to\n"
|
|
"%1 will stay the same.)")
|
|
.arg(QString::fromUtf8(obj->getName().c_str()))
|
|
.arg(QString::fromUtf8(obj->getName().c_str())),
|
|
tr("&Yes"), tr("&No"), QString::null,
|
|
0, 1 )==0 )
|
|
{
|
|
list<FWObject*> il = obj->getByType(Interface::TYPENAME);
|
|
for (list<FWObject*>::iterator i=il.begin(); i!=il.end(); ++i)
|
|
{
|
|
autorename(*i,IPv4::TYPENAME,"ip");
|
|
autorename(*i,physAddress::TYPENAME,"mac");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Interface::isA(obj))
|
|
{
|
|
if (!ask || QMessageBox::warning(
|
|
this,"Firewall Builder",
|
|
tr(
|
|
"The name of the interface '%1' has changed. The program can also\n"
|
|
"rename IP address objects that belong to this interface,\n"
|
|
"using standard naming scheme 'host_name:interface_name:ip'.\n"
|
|
"This makes it easier to distinguish what host or a firewall\n"
|
|
"given IP address object belongs to when it is used in \n"
|
|
"the policy or NAT rule. The program also renames MAC address\n"
|
|
"objects using scheme 'host_name:interface_name:mac'.\n"
|
|
"Do you want to rename child IP and MAC address objects now?\n"
|
|
"(If you click 'No', names of all address objects that belong to\n"
|
|
"%1 will stay the same.)")
|
|
.arg(QString::fromUtf8(obj->getName().c_str()))
|
|
.arg(QString::fromUtf8(obj->getName().c_str())),
|
|
tr("&Yes"), tr("&No"), QString::null,
|
|
0, 1 )==0 )
|
|
{
|
|
autorename(obj,IPv4::TYPENAME,"ip");
|
|
autorename(obj,physAddress::TYPENAME,"mac");
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::autorename(FWObject *obj,
|
|
const string &objtype,
|
|
const string &namesuffix)
|
|
{
|
|
FWObject *hst = obj->getParent();
|
|
list<FWObject*> ol = obj->getByType(objtype);
|
|
int sfxn = 1;
|
|
|
|
for (list<FWObject*>::iterator j=ol.begin(); j!=ol.end(); ++j,sfxn++)
|
|
{
|
|
QString sfx;
|
|
if (ol.size()==1) sfx="";
|
|
else sfx.setNum(sfxn);
|
|
QString nn = QString("%1:%2:%3%4")
|
|
.arg(QString::fromUtf8(hst->getName().c_str()))
|
|
.arg(QString::fromUtf8(obj->getName().c_str()))
|
|
.arg(namesuffix.c_str())
|
|
.arg(sfx);
|
|
|
|
(*j)->setName(string(nn.toUtf8()));
|
|
QTreeWidgetItem *itm1 = allItems[ *j ];
|
|
assert(itm1!=NULL);
|
|
itm1->setText(0, getTreeLabel( *j ) );
|
|
itm1->parent()->sortChildren(0, Qt::AscendingOrder);//();
|
|
}
|
|
ol.clear();
|
|
}
|
|
|
|
void ObjectManipulator::clearObjects()
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::clearObjects start");
|
|
|
|
invalidateDialog();
|
|
while (history.size()!=0) history.pop();
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::clearObjects history size: %d",
|
|
history.size());
|
|
|
|
int N=m_objectManipulator->libs->count();
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::clearObjects %d libs", N);
|
|
|
|
for (int i=N-1; i>=0; i--)
|
|
{
|
|
QTreeWidget *otv = idxToTrees[i];
|
|
assert(otv!=NULL);
|
|
m_objectManipulator->widgetStack->removeWidget( otv );
|
|
delete otv;
|
|
removeLib(i);
|
|
}
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::clearObjects idxToLibs size: %d",
|
|
idxToLibs.size());
|
|
if (fwbdebug) qDebug("ObjectManipulator::clearObjects idxToTrees size: %d",
|
|
idxToTrees.size());
|
|
|
|
idxToLibs.clear();
|
|
idxToTrees.clear();
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::clearObjects done");
|
|
}
|
|
|
|
void ObjectManipulator::loadObjects()
|
|
{
|
|
loadObjects( m_project->db() );
|
|
}
|
|
|
|
void ObjectManipulator::loadObjects(FWObjectDatabase *)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::loadObjects start");
|
|
|
|
if (m_objectManipulator->libs->count()!=0) clearObjects();
|
|
|
|
FWObject *firstUserLib=NULL;
|
|
list<FWObject*> ll = m_project->db()->getByType( Library::TYPENAME );
|
|
|
|
// ll.sort(FWObjectNameCmpPredicate());
|
|
|
|
for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++)
|
|
{
|
|
FWObject *lib = (*i);
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::loadObjects lib %p %s %s",
|
|
lib, lib->getId().c_str(), lib->getName().c_str() );
|
|
|
|
if ( lib->getId()==DELETED_LIB &&
|
|
! st->getBool("UI/ShowDeletedObjects")) continue;
|
|
|
|
if ( lib->getId()!=STANDARD_LIB &&
|
|
lib->getId()!=TEMPLATE_LIB &&
|
|
firstUserLib==NULL) firstUserLib=*i;
|
|
|
|
addTreePage( lib );
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::loadObjects added lib %s",
|
|
lib->getName().c_str());
|
|
}
|
|
|
|
if (firstUserLib==NULL) firstUserLib=ll.front();
|
|
openLib( firstUserLib );
|
|
}
|
|
|
|
void ObjectManipulator::addLib( FWObject *lib,QTreeWidget* otv)
|
|
{
|
|
QString newlibname = QString::fromUtf8(lib->getName().c_str());
|
|
int N = m_objectManipulator->libs->count();
|
|
int idx = 0;
|
|
vector<FWObject*>::iterator i1=idxToLibs.begin();
|
|
vector<QTreeWidget*>::iterator i2=idxToTrees.begin();
|
|
for ( ; idx<N; ++idx,++i1,++i2)
|
|
if ( m_objectManipulator->libs->itemText(idx) > newlibname ) break;
|
|
|
|
string icn=":/Icons/"+lib->getTypeName()+"/icon-tree";
|
|
//Resources::global_res->getObjResourceStr(lib,"icon-tree").c_str();
|
|
QPixmap pm;
|
|
if ( ! QPixmapCache::find( icn.c_str(), pm) )
|
|
{
|
|
pm.load( icn.c_str() );
|
|
QPixmapCache::insert( icn.c_str(), pm);
|
|
}
|
|
m_objectManipulator->libs->insertItem( idx, pm, newlibname);
|
|
// idx=libs->count()-1;
|
|
|
|
m_objectManipulator->libs->setCurrentIndex(idx);
|
|
|
|
idxToLibs.insert(i1,lib);
|
|
if (otv!=NULL) idxToTrees.insert(i2,otv);
|
|
|
|
}
|
|
|
|
void ObjectManipulator::addTreePage( FWObject *lib)
|
|
{
|
|
if (fwbdebug) qDebug("Object Manipulator::addTreePage");
|
|
|
|
ObjectTreeView *objTreeView = new ObjectTreeView(m_project, m_objectManipulator->widgetStack,
|
|
OBJTREEVIEW_WIDGET_NAME );
|
|
|
|
addLib(lib,objTreeView);
|
|
|
|
QSizePolicy policy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
policy.setHorizontalStretch(0);
|
|
policy.setVerticalStretch(0);
|
|
policy.setHeightForWidth(objTreeView->sizePolicy().hasHeightForWidth());
|
|
|
|
objTreeView->setSizePolicy(policy);
|
|
|
|
m_objectManipulator->widgetStack->addWidget( objTreeView );
|
|
m_objectManipulator->widgetStack->show();
|
|
objTreeView->show();
|
|
|
|
// objTreeView->setSelectionMode( QListView::Extended );
|
|
|
|
updateLibColor( lib );
|
|
// updateLibName( lib );
|
|
|
|
//objTreeView->setContextMenuPolicy( Qt::CustomContextMenu );
|
|
|
|
connect(m_objectManipulator->widgetStack, SIGNAL( currentChanged(int) ),
|
|
this, SLOT( currentTreePageChanged(int) ) );
|
|
|
|
connect(objTreeView,SIGNAL( editCurrentObject_sign() ),
|
|
this, SLOT( editSelectedObject()) );
|
|
|
|
connect(objTreeView,SIGNAL( editCurrentObject_sign() ),
|
|
this, SLOT( editSelectedObject()) );
|
|
|
|
connect(objTreeView,SIGNAL( switchObjectInEditor_sign(libfwbuilder::FWObject*) ),
|
|
this, SLOT( switchObjectInEditor(libfwbuilder::FWObject*)) );
|
|
|
|
connect( objTreeView, SIGNAL( deleteObject_sign(libfwbuilder::FWObject*) ),
|
|
this, SLOT( deleteObj() ) );
|
|
|
|
connect( objTreeView, SIGNAL( objectDropped_sign(libfwbuilder::FWObject*) ),
|
|
this, SLOT( openObject(libfwbuilder::FWObject*) ) );
|
|
|
|
connect( objTreeView, SIGNAL( contextMenuRequested_sign(const QPoint&) ),
|
|
this, SLOT( contextMenuRequested(const QPoint&) ) );
|
|
|
|
connect( objTreeView, SIGNAL( currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*) ),
|
|
this, SLOT( selectionChanged(QTreeWidgetItem*) ) );
|
|
|
|
|
|
ObjectTreeViewItem *itm1=new ObjectTreeViewItem( objTreeView );
|
|
|
|
itm1->setLib("");
|
|
itm1->setExpanded(TRUE);
|
|
|
|
/* need to enable dragging in order to avoid object highlighting in
|
|
* the tree when user drags mouse cursor */
|
|
|
|
itm1->setFlags(itm1->flags() | Qt::ItemIsDragEnabled);
|
|
|
|
itm1->setText( 0 , getTreeLabel( lib ) );
|
|
if (lib->isReadOnly())
|
|
{
|
|
QPixmap pm;
|
|
if ( ! QPixmapCache::find( ":/Icons/lock.png", pm) )
|
|
{
|
|
pm.load( ":/Icons/lock.png" );
|
|
QPixmapCache::insert( ":/Icons/lock.png", pm);
|
|
}
|
|
itm1->setIcon(0, pm );
|
|
} else
|
|
{
|
|
string icn=":/Icons/"+lib->getTypeName()+"/icon-tree";
|
|
//Resources::global_res->getObjResourceStr(lib,"icon-tree").c_str();
|
|
QPixmap pm;
|
|
if ( ! QPixmapCache::find( icn.c_str(), pm) )
|
|
{
|
|
pm.load( icn.c_str() );
|
|
QPixmapCache::insert( icn.c_str(), pm);
|
|
}
|
|
itm1->setIcon( 0, pm);
|
|
}
|
|
|
|
itm1->setProperty("id", lib->getId().c_str() );
|
|
itm1->setProperty("type", lib->getTypeName().c_str() );
|
|
itm1->setFWObject( lib );
|
|
allItems[lib] = itm1;
|
|
|
|
// objTreeView->setSelected( itm1, true );
|
|
|
|
for (list<FWObject*>::iterator m=lib->begin(); m!=lib->end(); m++)
|
|
insertSubtree( itm1, (*m) );
|
|
objTreeView->updateTreeItems();
|
|
objTreeView->sortByColumn(0,Qt::AscendingOrder);
|
|
}
|
|
|
|
void ObjectManipulator::removeLib(FWObject* lib)
|
|
{
|
|
removeLib( getIdxForLib(lib) );
|
|
}
|
|
|
|
void ObjectManipulator::removeLib(int id)
|
|
{
|
|
int N = m_objectManipulator->libs->count();
|
|
int idx = 0;
|
|
vector<FWObject*>::iterator i1=idxToLibs.begin();
|
|
vector<QTreeWidget*>::iterator i2=idxToTrees.begin();
|
|
for ( ; idx<N; ++idx,++i1,++i2)
|
|
{
|
|
if ( idx==id )
|
|
{
|
|
m_objectManipulator->libs->removeItem( idx );
|
|
idxToLibs.erase(i1);
|
|
idxToTrees.erase(i2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::currentTreePageChanged(int i)
|
|
{
|
|
QWidget *w = m_objectManipulator->widgetStack->widget(i);
|
|
switchingTrees(w);
|
|
}
|
|
|
|
void ObjectManipulator::switchingTrees(QWidget* w)
|
|
{
|
|
ObjectTreeView *new_otv = dynamic_cast<ObjectTreeView*>(w);
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::switchingTrees current_otv=%p new_otv=%p",
|
|
(void*)(current_tree_view),(void*)(new_otv));
|
|
|
|
if (!new_otv)
|
|
return;//assert(new_otv)
|
|
|
|
|
|
if (current_tree_view!=NULL) current_tree_view->becomingHidden();
|
|
new_otv->becomingVisible();
|
|
current_tree_view = new_otv;
|
|
|
|
}
|
|
|
|
void ObjectManipulator::makeNameUnique(FWObject* parent,FWObject* obj)
|
|
{
|
|
int suffix=1;
|
|
QString basename=QString::fromUtf8(obj->getName().c_str());
|
|
QString newname=basename;
|
|
|
|
/* check if there is another object with the same name */
|
|
while (parent->findObjectByName(obj->getTypeName(),newname.toLatin1().constData())!=NULL)
|
|
{
|
|
/* there is a duplicate */
|
|
newname=QString("%1-%2").arg(basename).arg(suffix);
|
|
suffix++;
|
|
}
|
|
obj->setName(string(newname.toUtf8()));
|
|
}
|
|
|
|
void ObjectManipulator::contextMenuRequested(const QPoint &pos)
|
|
{
|
|
/* in extended selection mode there may be several selected items */
|
|
|
|
QTreeWidget *objTreeView = getCurrentObjectTree();
|
|
QTreeWidgetItem *item = objTreeView->itemAt(pos);//clicked item
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::contextMenu selectedObjects.size=%d",
|
|
getCurrentObjectTree()->getNumSelected());
|
|
|
|
ObjectTreeViewItem *otvi=dynamic_cast<ObjectTreeViewItem*>(item);
|
|
if (otvi==NULL) return; // happens when user clicks outside an item
|
|
|
|
if (!getCurrentObjectTree()->isSelected(otvi->getFWObject()))
|
|
openObject( otvi , true );
|
|
|
|
if (currentObj==NULL) currentObj=otvi->getFWObject();
|
|
|
|
QMenu *popup=new QMenu(this);
|
|
|
|
QAction *edtID =popup->addAction( tr("Edit"), this, SLOT( editSelectedObject()));
|
|
|
|
QMenu *duptargets = new QMenu(popup);
|
|
QMenu *movetargets = new QMenu(popup);
|
|
|
|
connect ( movetargets, SIGNAL ( triggered(QAction*) ),
|
|
this, SLOT( moveObj(QAction*) ) );
|
|
connect ( duptargets, SIGNAL ( triggered(QAction*) ),
|
|
this, SLOT( duplicateObj(QAction*) ) );
|
|
|
|
/* we add " ... to library ..." submenu to the "Move " menu item only
|
|
* if user did not select a library, or if they selected several
|
|
* objects. Method moveObj knows that library should not be moved
|
|
* into another library.
|
|
*/
|
|
bool libSelected =
|
|
(getCurrentObjectTree()->getNumSelected()==1 &&
|
|
Library::isA(getCurrentObjectTree()->getSelectedObjects().front()));
|
|
|
|
int libid = 0;
|
|
|
|
FWObject *cl=getCurrentLib();
|
|
int moveTargets=0;
|
|
vector<FWObject*>::iterator i;
|
|
for (i=idxToLibs.begin(); i!=idxToLibs.end(); ++i,++libid)
|
|
{
|
|
FWObject *lib = *i;
|
|
|
|
/* can't move to the same library. Will use menu item 'create
|
|
* here' to duplicate to the same library
|
|
*/
|
|
if (lib==cl) continue;
|
|
|
|
if ( lib->getId()==STANDARD_LIB ||
|
|
lib->getId()==TEMPLATE_LIB ||
|
|
lib->getId()==DELETED_LIB ||
|
|
lib->isReadOnly())
|
|
continue;
|
|
QAction* dact=duptargets->addAction(
|
|
tr("place in library %1").arg(QString::fromUtf8(lib->getName().c_str()))/*,this, SLOT( duplicateObj(libid))*/
|
|
);
|
|
|
|
//duptargets->connectItem( did, this, SLOT( duplicateObj(int)) ); replaced with preprevious string
|
|
//duptargets->setItemParameter(did, libid ); replaced with next:
|
|
dact->setData(libid);
|
|
|
|
if (!libSelected)
|
|
{
|
|
QAction* mact=movetargets->addAction(
|
|
tr("to library %1").arg(QString::fromUtf8(lib->getName().c_str())));
|
|
|
|
mact->setData(libid);
|
|
|
|
moveTargets++;
|
|
}
|
|
}
|
|
|
|
duptargets->addAction(tr("place here"), this, SLOT( duplicateObjUnderSameParent()));
|
|
|
|
//QAction *dupID = duptargets->addAction( tr("Duplicate ...") ); // BUGFIX-2346
|
|
QAction *dupID = popup->addAction( tr("Duplicate ...") ,this, SLOT (duplicateObjUnderSameParent()));//popup->
|
|
QAction *movID;
|
|
|
|
if (moveTargets!=0)
|
|
{
|
|
movID=movetargets->addAction( tr("Move ...") );
|
|
} else
|
|
{
|
|
movID=popup->addAction( tr("Move ...") );
|
|
movID->setData(-1);
|
|
}
|
|
|
|
|
|
popup->addSeparator();
|
|
|
|
QAction *copyID = popup->addAction( tr("Copy") , this ,
|
|
SLOT( copyObj() ) );
|
|
QAction *cutID =popup->addAction( tr("Cut") , this ,
|
|
SLOT( cutObj() ) );
|
|
QAction *pasteID =popup->addAction( tr("Paste") , this ,
|
|
SLOT( pasteObj() ) );
|
|
|
|
popup->addSeparator();
|
|
|
|
QAction * delID =popup->addAction( tr("Delete") , this ,
|
|
SLOT( deleteObj() ) );
|
|
|
|
QAction *newID1=NULL;
|
|
QAction *newID2=NULL;
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==1)
|
|
{
|
|
popup->addSeparator();
|
|
|
|
if ( (Firewall::isA(currentObj) || Host::isA(currentObj)) &&
|
|
! currentObj->isReadOnly() )
|
|
newID1=popup->addAction( tr("Add Interface"), this ,
|
|
SLOT( newInterface() ) );
|
|
|
|
if (Interface::isA(currentObj) && ! currentObj->isReadOnly())
|
|
{
|
|
newID1=popup->addAction( tr("Add IP Address"), this ,
|
|
SLOT( newInterfaceAddress() ) );
|
|
newID2=popup->addAction( tr("Add MAC Address"), this ,
|
|
SLOT( newPhysicalAddress() ) );
|
|
}
|
|
|
|
if (currentObj->getPath(true)=="Firewalls")
|
|
newID1=popup->addAction( tr("New Firewall"), this ,
|
|
SLOT( newFirewall() ) );
|
|
|
|
if (currentObj->getPath(true)=="Objects/Addresses")
|
|
{
|
|
newID1=popup->addAction( tr("New Address"), this ,
|
|
SLOT( newAddress() ) );
|
|
}
|
|
if (currentObj->getPath(true)=="Objects/DNS Names")
|
|
{
|
|
newID1=popup->addAction( tr("New DNS Name"), this ,
|
|
SLOT( newDNSName() ) );
|
|
}
|
|
|
|
if (currentObj->getPath(true)=="Objects/Address Tables")
|
|
{
|
|
newID1=popup->addAction( tr("New Address Table"), this ,
|
|
SLOT( newAddressTable() ) );
|
|
}
|
|
|
|
if (currentObj->getPath(true)=="Objects/Address Ranges")
|
|
newID1=popup->addAction( tr("New Address Range"), this ,
|
|
SLOT( newAddressRange() ) );
|
|
|
|
if (currentObj->getPath(true)=="Objects/Hosts")
|
|
newID1=popup->addAction( tr("New Host"), this ,
|
|
SLOT( newHost() ) );
|
|
|
|
if (currentObj->getPath(true)=="Objects/Networks")
|
|
newID1=popup->addAction( tr("New Network"), this ,
|
|
SLOT( newNetwork() ) );
|
|
|
|
if (currentObj->getPath(true)=="Objects/Groups")
|
|
newID1=popup->addAction( tr("New Group"), this ,
|
|
SLOT( newObjectGroup() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/Custom")
|
|
newID1=popup->addAction( tr("New Custom Service"),this ,
|
|
SLOT( newCustom() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/IP")
|
|
newID1=popup->addAction( tr("New IP Service"), this ,
|
|
SLOT( newIP() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/ICMP")
|
|
newID1=popup->addAction( tr("New ICMP Service"), this ,
|
|
SLOT( newICMP() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/TCP")
|
|
newID1=popup->addAction( tr("New TCP Service"), this ,
|
|
SLOT( newTCP() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/UDP")
|
|
newID1=popup->addAction( tr("New UDP Service"), this ,
|
|
SLOT( newUDP() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/TagServices")
|
|
newID1=popup->addAction( tr("New TagService"), this ,
|
|
SLOT( newTagService() ) );
|
|
|
|
if (currentObj->getPath(true)=="Services/Groups")
|
|
newID1=popup->addAction( tr("New Group"), this ,
|
|
SLOT( newServiceGroup() ) );
|
|
|
|
if (currentObj->getPath(true)=="Time")
|
|
newID1=popup->addAction( tr("New Time Interval"), this ,
|
|
SLOT( newInterval() ) );
|
|
|
|
popup->addSeparator();
|
|
popup->addAction( tr("Find") , this , SLOT( findObject()));
|
|
popup->addAction( tr("Where used") , this , SLOT( findWhereUsedSlot()));
|
|
/*
|
|
if (Firewall::cast(currentObj)!=NULL)
|
|
{
|
|
popup->addSeparator();
|
|
popup->addAction( tr("Compile") , this , SLOT( compile()));
|
|
popup->addAction( tr("Install") , this , SLOT( install()));
|
|
}
|
|
*/
|
|
} else
|
|
{
|
|
|
|
popup->addAction( tr("Group"), this ,
|
|
SLOT( groupObjects() ) );
|
|
|
|
}
|
|
|
|
if (Firewall::cast(currentObj)!=NULL || ObjectGroup::cast(currentObj)!=NULL)
|
|
{
|
|
popup->addSeparator();
|
|
popup->addAction( tr("Compile") , this , SLOT( compile()));
|
|
popup->addAction( tr("Install") , this , SLOT( install()));
|
|
|
|
// popup->addSeparator();
|
|
// popup->addAction( tr("Simulate install") , this , SLOT( simulateInstall()));
|
|
}
|
|
|
|
popup->addSeparator();
|
|
QAction* lcID=popup->addAction( tr("Lock"), this ,
|
|
SLOT( lockObject() ) );
|
|
QAction* unlcID=popup->addAction( tr("Unlock"), this ,
|
|
SLOT( unlockObject() ) );
|
|
lcID->setEnabled(getCurrentObjectTree()->isLockable());
|
|
unlcID->setEnabled(getCurrentObjectTree()->isUnlockable());
|
|
|
|
if (fwbdebug)
|
|
{
|
|
/* keep this for debugging */
|
|
popup->addSeparator();
|
|
popup->addAction( tr("dump") , this , SLOT( dumpObj()));
|
|
}
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==1)
|
|
{
|
|
edtID->setEnabled(! m_project->isSystem(currentObj) );
|
|
} else
|
|
edtID->setEnabled(false);
|
|
|
|
bool dupMenuItem=true;
|
|
bool moveMenuItem=true;
|
|
bool copyMenuItem=true;
|
|
bool pasteMenuItem=true;
|
|
bool delMenuItem=true;
|
|
bool newMenuItem=true;
|
|
bool inDeletedObjects = false;
|
|
|
|
getMenuState( (moveTargets>0),
|
|
dupMenuItem,moveMenuItem,copyMenuItem,pasteMenuItem,
|
|
delMenuItem,newMenuItem,inDeletedObjects);
|
|
|
|
dupID->setEnabled(dupMenuItem);
|
|
movID->setEnabled(moveMenuItem);
|
|
copyID->setEnabled(copyMenuItem);
|
|
pasteID->setEnabled(pasteMenuItem);
|
|
|
|
cutID->setEnabled(copyMenuItem);
|
|
delID->setEnabled(delMenuItem);
|
|
|
|
if (newID1)
|
|
newID1->setEnabled(newMenuItem);
|
|
if (newID2)
|
|
newID2->setEnabled(newMenuItem);
|
|
|
|
|
|
if (inDeletedObjects) movID->setText( tr("Undelete...") );
|
|
|
|
popup->exec( objTreeView->mapToGlobal( pos ) );
|
|
}
|
|
|
|
void ObjectManipulator::getMenuState(bool haveMoveTargets,
|
|
bool &dupMenuItem,
|
|
bool &moveMenuItem,
|
|
bool ©MenuItem,
|
|
bool &pasteMenuItem,
|
|
bool &delMenuItem,
|
|
bool &newMenuItem,
|
|
bool &inDeletedObjects)
|
|
{
|
|
dupMenuItem=true;
|
|
moveMenuItem=true;
|
|
copyMenuItem=true;
|
|
pasteMenuItem=true;
|
|
delMenuItem=true;
|
|
newMenuItem=true;
|
|
|
|
inDeletedObjects = false;
|
|
|
|
FWObject *delObjLib =
|
|
m_project->db()->findInIndex( FWObjectDatabase::getDeletedObjectsId());
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSelectedObjects();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
FWObject *obj= *i;
|
|
|
|
QString objPath = obj->getPath(true).c_str();
|
|
|
|
copyMenuItem = copyMenuItem && m_project->getCopyMenuState(objPath);
|
|
pasteMenuItem = pasteMenuItem &&
|
|
m_project->getPasteMenuState(objPath) &&
|
|
(FWObjectClipboard::obj_clipboard->size()!=0);
|
|
delMenuItem = delMenuItem && m_project->getDeleteMenuState(objPath);
|
|
|
|
if (pasteMenuItem)
|
|
{
|
|
/*
|
|
* enable Paste menu item only if object can be pasted
|
|
*/
|
|
vector<string>::iterator i;
|
|
for (i= FWObjectClipboard::obj_clipboard->begin();
|
|
i!=FWObjectClipboard::obj_clipboard->end(); ++i)
|
|
{
|
|
FWObject *co= m_project->db()->findInIndex(*i);
|
|
if (co==NULL)
|
|
{
|
|
continue ;
|
|
//QString s2 = obj->getTypeName().c_str();
|
|
}
|
|
QString s3 = obj->getTypeName().c_str();
|
|
FWObject *nobj=pasteTo( obj , co , false, true);
|
|
pasteMenuItem = pasteMenuItem && (nobj!=NULL);
|
|
}
|
|
}
|
|
|
|
dupMenuItem=
|
|
(dupMenuItem && ! m_project->isSystem(obj) && ! Library::isA(obj) );
|
|
|
|
inDeletedObjects = (delObjLib!=NULL && obj->isChildOf(delObjLib));
|
|
dupMenuItem = dupMenuItem && !inDeletedObjects;
|
|
|
|
// can't move system objects
|
|
moveMenuItem = moveMenuItem && ! m_project->isSystem(obj);
|
|
|
|
// can't move interfaces unless parent host object is also selected
|
|
if ( Interface::isA(obj) &&
|
|
std::find(so.begin(),so.end(),obj->getParent())==so.end())
|
|
moveMenuItem = false;
|
|
|
|
// can't move ip addresses if parent is interface
|
|
if (IPv4::isA(obj) && Interface::isA(obj->getParent()))
|
|
moveMenuItem = false;
|
|
|
|
// can't move physAddress objects
|
|
moveMenuItem = moveMenuItem && ! physAddress::isA(obj);
|
|
|
|
// can't move read-only objects
|
|
moveMenuItem = moveMenuItem && ! obj->isReadOnly();
|
|
|
|
// can't move libraries unless in deleted objects
|
|
if (Library::isA(obj) && ! inDeletedObjects) moveMenuItem = false;
|
|
|
|
// can't move if there is only one user-defined library in the tree
|
|
// but we dont care about number of libraries if this will become
|
|
// 'undelete' operation
|
|
if (!haveMoveTargets && ! inDeletedObjects) moveMenuItem = false;
|
|
|
|
// copyMenuItem= (copyMenuItem &&
|
|
// ! m_project->isSystem(currentObj) &&
|
|
// ! Library::isA(currentObj));
|
|
// delMenuItem= (delMenuItem && ! m_project->isSystem(currentObj));
|
|
|
|
newMenuItem= (newMenuItem && ! obj->isReadOnly() );
|
|
Interface *intf = Interface::cast(obj);
|
|
if (intf &&
|
|
(intf->isDyn() ||
|
|
intf->isUnnumbered() ||
|
|
intf->isBridgePort())
|
|
)
|
|
newMenuItem = false;
|
|
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::find()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
if (obj==NULL) return;
|
|
m_project->setFDObject(obj);
|
|
}
|
|
void ObjectManipulator::findObject()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
if (obj==NULL) return;
|
|
m_project->findObject( obj );
|
|
}
|
|
|
|
void ObjectManipulator::dumpObj()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
if (obj==NULL) return;
|
|
obj->dump(false,false);
|
|
}
|
|
|
|
void ObjectManipulator::compile()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
|
|
set<Firewall*> fo;
|
|
filterFirewallsFromSelection(so,fo);
|
|
|
|
//FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
//if (obj==NULL) return;
|
|
//m_project->showFirewall(obj);
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::compile filtered %d firewalls",fo.size());
|
|
m_project->compile(fo);
|
|
}
|
|
void ObjectManipulator::filterFirewallsFromSelection(vector<FWObject*> &so,set<Firewall*> &fo)
|
|
{
|
|
Firewall *fw;
|
|
ObjectGroup *gr;
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
fw= Firewall::cast( *i );
|
|
if (fw!=NULL)
|
|
{
|
|
fo.insert(fw);
|
|
continue;
|
|
}
|
|
gr=ObjectGroup::cast( *i);
|
|
if (gr!=NULL)
|
|
{
|
|
extractFirewallsFromGroup(gr,fo);
|
|
}
|
|
}
|
|
|
|
}
|
|
void ObjectManipulator::extractFirewallsFromGroup(ObjectGroup *gr,set<Firewall*> &fo)
|
|
{
|
|
Firewall *f;
|
|
set<FWObject*> oset;
|
|
m_project->db()->findObjectsInGroup(gr,oset);
|
|
|
|
set<FWObject*>::iterator i;
|
|
for(i=oset.begin();i!=oset.end();++i)
|
|
{
|
|
f=Firewall::cast(*i);
|
|
if (f!=NULL) fo.insert(f);
|
|
}
|
|
}
|
|
void ObjectManipulator::install()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
//FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
//if (obj==NULL) return;
|
|
//m_project->showFirewall(obj);
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
set<Firewall*> fo;
|
|
filterFirewallsFromSelection(so,fo);
|
|
|
|
|
|
|
|
m_project->install(fo);
|
|
}
|
|
|
|
FWObject* ObjectManipulator::duplicateObject(FWObject *targetLib,
|
|
FWObject *obj,
|
|
const QString &name,
|
|
bool askForAutorename)
|
|
{
|
|
if (!isTreeReadWrite(this, targetLib)) return NULL;
|
|
|
|
openLib(targetLib);
|
|
|
|
FWObject *o=NULL;
|
|
|
|
QString n;
|
|
if (!name.isEmpty()) n=name;
|
|
else n=QString::fromUtf8(obj->getName().c_str());
|
|
|
|
o=createObject(obj->getTypeName().c_str(), n, obj);
|
|
if (o)
|
|
{
|
|
openObject(o);
|
|
if (!o->isReadOnly() && (Host::isA(o) || Firewall::isA(o) || Interface::isA(o)) )
|
|
autorename(o,askForAutorename);
|
|
}
|
|
return o;
|
|
}
|
|
|
|
void ObjectManipulator::duplicateObj(QAction *action)
|
|
{
|
|
int libid = action->data().toInt();
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
ObjectTreeView* ot=getCurrentObjectTree();
|
|
ot->freezeSelection(true);
|
|
FWObject *obj;
|
|
FWObject *nobj = NULL;
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
|
|
if ( m_project->isSystem(obj) || Interface::isA(obj) ) continue;
|
|
|
|
FWObject *cl = idxToLibs[libid];
|
|
|
|
nobj = duplicateObject(cl,obj,"",false);
|
|
|
|
if (nobj->getTypeName()==Firewall::TYPENAME)
|
|
{
|
|
m_project->addFirewallToList(nobj);
|
|
m_project->showFirewall(nobj);
|
|
}
|
|
}
|
|
editObject(nobj);
|
|
ot->freezeSelection(false);
|
|
}
|
|
|
|
void ObjectManipulator::duplicateObjUnderSameParent()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
ObjectTreeView* ot=getCurrentObjectTree();
|
|
ot->freezeSelection(true);
|
|
FWObject *obj;
|
|
FWObject *o = NULL;
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
|
|
o=NULL;
|
|
|
|
QString n=QString::fromUtf8(obj->getName().c_str());
|
|
|
|
openObject(o=createObject(obj->getParent(),
|
|
obj->getTypeName().c_str(), n, obj));
|
|
|
|
if (Host::isA(o) || Firewall::isA(o) || Interface::isA(o))
|
|
autorename(o,false);
|
|
|
|
if (Firewall::isA(o))
|
|
{
|
|
m_project->addFirewallToList(o);
|
|
m_project->showFirewall(o);
|
|
}
|
|
}
|
|
if (o!=NULL) editObject(o);
|
|
ot->freezeSelection(false);
|
|
}
|
|
|
|
void ObjectManipulator::moveObject(FWObject *targetLib, FWObject *obj)
|
|
{
|
|
FWObject *cl=getCurrentLib();
|
|
if (cl==targetLib) return;
|
|
|
|
// bool inDeletedObjects = (obj->getParent()->getId()==FWObjectDatabase::getDeletedObjectsId());
|
|
|
|
// QString parentType;
|
|
// QString parentName;
|
|
FWObject *grp = NULL;
|
|
|
|
if (FWObjectDatabase::isA(targetLib)) grp = targetLib;
|
|
else
|
|
{
|
|
grp=m_project->getStandardSlotForObject(targetLib,
|
|
obj->getTypeName().c_str());
|
|
}
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject grp= %p", grp);
|
|
|
|
if (grp==NULL) grp=targetLib;
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject grp= %s",grp->getName().c_str());
|
|
|
|
if (!grp->isReadOnly())
|
|
{
|
|
obj->ref();
|
|
obj->ref();
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject removing from the widget");
|
|
|
|
ObjectTreeViewItem *itm = allItems[obj];
|
|
if (itm->parent()==NULL) return;
|
|
|
|
itm->parent()->takeChild(itm->parent()->indexOfChild(itm));
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject removing from the tree");
|
|
|
|
obj->getParent()->remove(obj);
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject adding to the tree");
|
|
|
|
grp->add(obj);
|
|
obj->unref();
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject adding to the widget");
|
|
|
|
if (allItems[grp]==NULL)
|
|
{
|
|
/* adding to the root, there is not such tree item */
|
|
if (Library::isA(obj))
|
|
{
|
|
addTreePage(obj);
|
|
openLib(obj);
|
|
} else
|
|
{
|
|
/* it screwed up, just print debugging message */
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject no place in the tree corresponding to the object %p %s",grp,grp->getName().c_str());
|
|
}
|
|
} else
|
|
allItems[grp]->addChild(itm);
|
|
|
|
if (Firewall::cast(obj)!=NULL)
|
|
{
|
|
m_project->addFirewallToList(obj);
|
|
m_project->showFirewall(obj);
|
|
}
|
|
}
|
|
|
|
// if (fwbdebug)
|
|
// qDebug("ObjectManipulator::moveObject open lib cl %s",
|
|
// cl->getName().c_str());
|
|
// openLib(cl);
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject all done");
|
|
}
|
|
|
|
/*
|
|
* targetLibName is the name of the target library in Unicode
|
|
*/
|
|
void ObjectManipulator::moveObject(const QString &targetLibName,
|
|
FWObject *obj)
|
|
{
|
|
list<FWObject*> ll = m_project->db()->getByType( Library::TYPENAME );
|
|
for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++)
|
|
{
|
|
FWObject *lib=*i;
|
|
if (targetLibName==QString::fromUtf8(lib->getName().c_str()))
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::moveObject found lib %s",
|
|
lib->getName().c_str() );
|
|
|
|
moveObject(lib,obj);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::moveObj(QAction* action)
|
|
{
|
|
int libid = action->data().toInt();
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
ObjectTreeView* ot=getCurrentObjectTree();
|
|
ot->freezeSelection(true);
|
|
FWObject *obj;
|
|
|
|
FWObject *targetLib = idxToLibs[libid];
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("ObjectManipulator::moveObj obj=%p obj: %s",
|
|
obj, obj->getName().c_str() );
|
|
}
|
|
if (Library::isA(obj))
|
|
{
|
|
/* We can only move library to the root of the tree. This case only
|
|
* happens when user tries to undelete a library.
|
|
*/
|
|
moveObject(m_project->db(),obj);
|
|
} else
|
|
{
|
|
if (obj->isChildOf(targetLib)) continue;
|
|
|
|
if ( m_project->isSystem(obj) ||
|
|
Interface::isA(obj) ||
|
|
Interface::isA(obj->getParent())) continue;
|
|
|
|
moveObject(targetLib,obj);
|
|
}
|
|
}
|
|
ot->freezeSelection(false);
|
|
}
|
|
|
|
void ObjectManipulator::copyObj()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
FWObject *obj;
|
|
FWObjectClipboard::obj_clipboard->clear();
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
if ( ! m_project->isSystem(obj) )
|
|
FWObjectClipboard::obj_clipboard->add( obj,m_project );
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::cutObj()
|
|
{
|
|
copyObj();
|
|
deleteObj(); // works with the list getCurrentObjectTree()->getSelectedObjects()
|
|
}
|
|
|
|
void ObjectManipulator::pasteObj()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
if (obj==NULL) return;
|
|
vector<string>::iterator i;
|
|
int idx = 0;
|
|
for (i= FWObjectClipboard::obj_clipboard->begin(); i!=FWObjectClipboard::obj_clipboard->end(); ++i)
|
|
{
|
|
FWObject *co= FWObjectClipboard::obj_clipboard->getObjectByIdx(idx); //win->db()->findInIndex(*i);
|
|
copyObjWithDeep(co);
|
|
/*FWObject *nobj=pasteTo( obj , co );
|
|
if (nobj!=NULL)
|
|
{
|
|
if (Firewall::isA(nobj)) m_project->addFirewallToList(nobj);
|
|
if (Firewall::isA(obj)) m_project->showFirewall(obj);
|
|
}*/
|
|
}
|
|
}
|
|
|
|
|
|
|
|
FWObject* ObjectManipulator::pasteTo(FWObject *target,FWObject *obj,
|
|
bool openobj,bool validateOnly, bool renew_id)
|
|
{
|
|
FWObject *ta=target;
|
|
if (IPv4::isA(ta)) ta=ta->getParent();
|
|
try
|
|
{
|
|
/* clipboard holds a copy of the object */
|
|
// if (ta->getTypeName()==obj->getTypeName()) ta=ta->getParent();
|
|
|
|
Host *hst = Host::cast(ta); // works for firewall, too
|
|
Interface *intf = Interface::cast(ta);
|
|
|
|
if (m_project->isSystem(ta))
|
|
{
|
|
if (!m_project->validateForInsertion(ta,obj))
|
|
{
|
|
if (validateOnly) return NULL;
|
|
|
|
QMessageBox::warning(
|
|
this,"Firewall Builder",
|
|
QObject::tr("Impossible to insert object %1 (type %2) into %3\nbecause of incompatible type.")
|
|
.arg(obj->getName().c_str())
|
|
.arg(obj->getTypeName().c_str())
|
|
.arg(target->getName().c_str()),
|
|
"&Continue", QString::null, QString::null,
|
|
0, 1 );
|
|
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
if ( m_project->isSystem(ta) ||
|
|
(hst!=NULL && hst->validateChild(obj)) ||
|
|
(intf!=NULL && intf->validateChild(obj))
|
|
)
|
|
{
|
|
if (validateOnly) return obj;
|
|
|
|
/* add a copy of the object to system group */
|
|
|
|
FWObject *nobj=
|
|
m_project->db()->create(obj->getTypeName());
|
|
assert (nobj!=NULL);
|
|
nobj->ref();
|
|
nobj->duplicate(obj,renew_id); //if renew_id == true creates new object ID
|
|
|
|
makeNameUnique(ta,nobj);
|
|
ta->add( nobj );
|
|
insertSubtree( allItems[ta], nobj);
|
|
|
|
if (openobj) openObject(nobj);
|
|
|
|
return nobj;
|
|
}
|
|
|
|
Group *grp=Group::cast(ta);
|
|
|
|
if (grp!=NULL && grp->validateChild(obj))
|
|
{
|
|
if (validateOnly) return obj;
|
|
|
|
/* check for duplicates. We just won't add an object if it is already there */
|
|
string cp_id=obj->getId();
|
|
list<FWObject*>::iterator j;
|
|
for(j=grp->begin(); j!=grp->end(); ++j)
|
|
{
|
|
FWObject *o1=*j;
|
|
if(cp_id==o1->getId()) return o1;
|
|
|
|
FWReference *ref;
|
|
if( (ref=FWReference::cast(o1))!=NULL &&
|
|
cp_id==ref->getPointerId()) return o1;
|
|
}
|
|
|
|
grp->addRef(obj);
|
|
if (openobj) openObject(grp);
|
|
}
|
|
}
|
|
catch(FWException &ex)
|
|
{
|
|
if (validateOnly) return NULL;
|
|
|
|
QMessageBox::warning(
|
|
this,"Firewall Builder",
|
|
ex.toString().c_str(),
|
|
"&Continue", QString::null,QString::null,
|
|
0, 1 );
|
|
}
|
|
|
|
if (validateOnly) return NULL;
|
|
return obj;
|
|
}
|
|
|
|
|
|
|
|
void ObjectManipulator::lockObject()
|
|
{
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::lockObject selected %d objects ",
|
|
getCurrentObjectTree()->getNumSelected());
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj;
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
FWObject *lib = obj->getLibrary();
|
|
// these lbraries are locked anyway, do not let the user
|
|
// lock objects inside because they won't be able to unlock them.
|
|
if (lib->getId()!=STANDARD_LIB && lib->getId()!=TEMPLATE_LIB)
|
|
obj->setReadOnly(true);
|
|
}
|
|
getCurrentObjectTree()->setLockFlags();
|
|
getCurrentObjectTree()->updateTreeItems();
|
|
}
|
|
|
|
void ObjectManipulator::unlockObject()
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::unlockObject selected %d objects ",
|
|
getCurrentObjectTree()->getNumSelected());
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj;
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
FWObject *lib = obj->getLibrary();
|
|
if (lib->getId()!=STANDARD_LIB && lib->getId()!=TEMPLATE_LIB)
|
|
obj->setReadOnly(false);
|
|
}
|
|
getCurrentObjectTree()->setLockFlags();
|
|
getCurrentObjectTree()->updateTreeItems();
|
|
}
|
|
|
|
void ObjectManipulator::deleteObj()
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::deleteObj selected %d objects ",
|
|
getCurrentObjectTree()->getNumSelected());
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj;
|
|
bool emptyingTrash = false;
|
|
bool emptyingTrashInLib = false;
|
|
|
|
FWObject *delObjLib = m_project->db()->findInIndex(FWObjectDatabase::getDeletedObjectsId());
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::deleteObj delObjLib=%p",delObjLib);
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
|
|
if (delObjLib!=NULL)
|
|
{
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
emptyingTrash |= obj->isChildOf(delObjLib);
|
|
}
|
|
}
|
|
|
|
emptyingTrashInLib = emptyingTrash && m_project->editingLibrary();
|
|
|
|
/* Ask user iff:
|
|
*
|
|
* we are emptying trash while editing library file (.fwl)
|
|
* else
|
|
*
|
|
* if we are not emptying Trash (i.e. not deleting "Deleted objects" library)
|
|
* and
|
|
* (we delete more than one object
|
|
* or
|
|
* we delete one object and it is not a library (because in this case
|
|
* we ask them later anyway))
|
|
*/
|
|
|
|
QString msg;
|
|
|
|
if (emptyingTrashInLib)
|
|
{
|
|
msg = tr(
|
|
"Emptying the 'Deleted Objects' in a library file is not recommended.\n"
|
|
"When you remove deleted objects from a library file, Firewall Builder\n"
|
|
"loses ability to track them. If a group or a policy rule in some\n"
|
|
"data file still uses removed object from this library, you may encounter\n"
|
|
"unusual and unexpected behavior of the program.\n"
|
|
"Do you want to delete selected objects anyway ?"
|
|
);
|
|
if (QMessageBox::warning(
|
|
this,"Firewall Builder", msg,
|
|
tr("&Yes"), tr("&No"), QString::null,
|
|
0, 1 )!=0) return;
|
|
} else
|
|
{
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::deleteObj emptyingTrash=%d so.size=%d so.front()->type=%s",
|
|
emptyingTrash,
|
|
so.size(),
|
|
so.front()->getTypeName().c_str() );
|
|
|
|
|
|
if (!emptyingTrash && (so.size()>1 || !Library::isA(so.front())))
|
|
{
|
|
/*
|
|
msg = tr(
|
|
"When you delete an object, it is removed from the tree and\n"
|
|
"all groups and firewall policy rules that reference it.\n"
|
|
"Do you want to delete selected objects ?"
|
|
);
|
|
if (QMessageBox::warning(
|
|
this,"Firewall Builder", msg,
|
|
tr("&Yes"), tr("&No"), QString::null,
|
|
0, 1 )!=0) return;
|
|
*/
|
|
QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) );
|
|
ConfirmDeleteObjectDialog * dlg= new ConfirmDeleteObjectDialog(this);
|
|
|
|
dlg->load(so);
|
|
|
|
QApplication::restoreOverrideCursor();
|
|
if(dlg->exec()==QDialog::Rejected ) return;
|
|
}
|
|
}
|
|
|
|
|
|
/* need to work with a copy of the list of selected objects because
|
|
* some of the methods we call below clear list
|
|
* getCurrentObjectTree()->getSelectedObjects()
|
|
*/
|
|
|
|
vector<FWObject*> so2 = so;
|
|
|
|
if (fwbdebug)
|
|
{
|
|
for (vector<FWObject*>::iterator i=so2.begin(); i!=so2.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
qDebug("ObjectManipulator::deleteObj will delete obj=%p ( %s %s ) ",
|
|
obj, obj->getTypeName().c_str(), obj->getName().c_str());
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
for (vector<FWObject*>::iterator i=so2.begin(); i!=so2.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
|
|
// openObject(obj,false);
|
|
|
|
if ( ! m_project->isSystem(obj) )
|
|
{
|
|
if (Library::isA(obj))
|
|
{
|
|
list<FWObject*> ll=m_project->db()->getByType(Library::TYPENAME);
|
|
if (ll.size()==1) return;
|
|
|
|
if (QMessageBox::warning(
|
|
this,"Firewall Builder",
|
|
tr(
|
|
"When you delete a library, all objects that belong to it\n"
|
|
"disappear from the tree and all groups and rules that reference them.\n"
|
|
"You won't be able to reverse this operation later.\n"
|
|
"Do you still want to delete library %1?")
|
|
.arg(QString::fromUtf8(obj->getName().c_str())),
|
|
tr("&Yes"), tr("&No"), QString::null,
|
|
0, 1 )!=0 ) continue;
|
|
}
|
|
|
|
if (m_project->isEditorVisible() && m_project->getOpenedEditor()==obj) m_project->hideEditor();
|
|
|
|
delObj(obj);
|
|
}
|
|
}
|
|
}
|
|
catch(FWException &ex)
|
|
{
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::delObj(FWObject *obj,bool openobj)
|
|
{
|
|
if (obj->getId()==STANDARD_LIB || obj->getId()==DELETED_LIB) return;
|
|
|
|
m_project->findObjectWidget->reset();
|
|
try
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::delObj delete obj %p %s openobj=%d",
|
|
obj,obj->getName().c_str(),openobj);
|
|
|
|
FWObject *parent=obj->getParent();
|
|
FWObject *delObjLib = m_project->db()->findInIndex( DELETED_LIB );
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::delObj deleted obj lib %p",
|
|
delObjLib);
|
|
|
|
bool islib = Library::isA(obj);
|
|
// bool isintf = (Interface::isA(obj) && Firewall::isA(parent));
|
|
bool isfw = Firewall::isA(obj);
|
|
bool isDelObj = (delObjLib!=NULL && obj->isChildOf(delObjLib));
|
|
|
|
if (!islib && !isDelObj && obj->getId()!=TEMPLATE_LIB)
|
|
updateLastModifiedTimestampForAllFirewalls(obj);
|
|
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::delObj delete islib=%d isfw=%d isDelObj=%d",islib,isfw,isDelObj);
|
|
|
|
/*
|
|
* TODO: we have to remove not only the object, but also all its child
|
|
* objects from the database, as well as all references to them. This
|
|
* logic should really be in FWObject::removeAllInstances(FWObject*);
|
|
*/
|
|
|
|
/* remove from our internal tables before it is removed from the
|
|
* object tree so we could use obj->getId()
|
|
*/
|
|
if (islib && !isDelObj)
|
|
{
|
|
int idx = getIdxForLib(obj);
|
|
QTreeWidget *otv = idxToTrees[idx];
|
|
assert(otv!=NULL);
|
|
m_objectManipulator->widgetStack->removeWidget( otv );
|
|
removeLib(idx);
|
|
|
|
list<FWObject*> fl;
|
|
findFirewalls(obj, fl);
|
|
for (list<FWObject*>::iterator i=fl.begin(); i!=fl.end(); i++)
|
|
m_project->deleteFirewall( *i );
|
|
}
|
|
|
|
if (isfw && !isDelObj) m_project->deleteFirewall(obj);
|
|
|
|
|
|
// removeObjectFromTreeView(obj);
|
|
|
|
QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) );
|
|
|
|
if (islib && obj->isReadOnly()) obj->setReadOnly(false);
|
|
|
|
if (obj->getId()==TEMPLATE_LIB) // special case
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::delObj: special case: deleting template library");
|
|
m_project->db()->removeAllInstances(obj);
|
|
} else
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::delObj: recursively deleting library and all its objects");
|
|
m_project->db()->recursivelyRemoveObjFromTree(obj, false);
|
|
if (islib) parent=m_project->db()->getFirstByType(Library::TYPENAME);
|
|
}
|
|
|
|
QApplication::restoreOverrideCursor();
|
|
if (fwbdebug) qDebug("ObjectManipulator::delObj: done");
|
|
|
|
removeObjectFromTreeView(obj);
|
|
m_project->scheduleRuleSetRedraw();
|
|
|
|
if (!isDelObj)
|
|
{
|
|
if (allItems[delObjLib]!=NULL)
|
|
insertSubtree( allItems[delObjLib], obj );
|
|
} else
|
|
FWObjectClipboard::obj_clipboard->clear();
|
|
|
|
if (openobj)
|
|
{
|
|
if (isfw && !isDelObj)
|
|
{
|
|
std::list<Firewall*> fwlist;
|
|
findAllFirewalls(fwlist);
|
|
if (fwlist.size()>0)
|
|
{
|
|
FWObject *first_fw = fwlist.front();
|
|
if (first_fw!=NULL)
|
|
{
|
|
m_project->showFirewall( first_fw );
|
|
openObject( first_fw );
|
|
}
|
|
}
|
|
//QTimer::singleShot( 0, m_project, SLOT(reopenFirewall()) );
|
|
} else {
|
|
openObject(parent);
|
|
}
|
|
}
|
|
}
|
|
catch(FWException &ex)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::delObj: catch: restoreOverrideCursor");
|
|
QApplication::restoreOverrideCursor();
|
|
QMessageBox::warning(
|
|
this,"Firewall Builder",
|
|
ex.toString().c_str(),
|
|
"&Continue", QString::null,QString::null,
|
|
0, 1 );
|
|
throw(ex);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::groupObjects()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *co = getCurrentObjectTree()->getSelectedObjects().front();
|
|
|
|
newGroupDialog ngd( this );
|
|
|
|
if (ngd.exec()==QDialog::Accepted)
|
|
{
|
|
QString objName = ngd.m_dialog->obj_name->text();
|
|
QString libName = ngd.m_dialog->libs->currentText();
|
|
|
|
QString type = ObjectGroup::TYPENAME;
|
|
if (Service::cast(co)!=NULL) type=ServiceGroup::TYPENAME;
|
|
if (Interval::cast(co)!=NULL) type=IntervalGroup::TYPENAME;
|
|
|
|
FWObject *newgrp=NULL;
|
|
|
|
list<FWObject*> ll = m_project->db()->getByType( Library::TYPENAME );
|
|
for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++)
|
|
{
|
|
FWObject *lib=*i;
|
|
if (libName==QString::fromUtf8(lib->getName().c_str()))
|
|
{
|
|
/* TODO: need to show a dialog and say that chosen library is read-only.
|
|
* this is not critical though since newGroupDialog fills the pull-down
|
|
* only with names of read-write libraries
|
|
*/
|
|
if (lib->isReadOnly()) return;
|
|
FWObject *parent = m_project->getStandardSlotForObject(lib,type);
|
|
if (parent==NULL)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::groupObjects(): could not find standard slot for object of type %s in library %s",
|
|
type.toAscii().constData(),lib->getName().c_str());
|
|
return;
|
|
}
|
|
newgrp = createObject(parent,type,objName);
|
|
|
|
break;
|
|
}
|
|
}
|
|
if (newgrp==NULL) return;
|
|
|
|
FWObject *obj;
|
|
|
|
ObjectTreeView* ot=getCurrentObjectTree();
|
|
ot->freezeSelection(true);
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
obj= *i;
|
|
newgrp->addRef(obj);
|
|
}
|
|
ot->freezeSelection(false);
|
|
|
|
openObject(newgrp);
|
|
editObject(newgrp);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::info()
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::info()");
|
|
|
|
if (currentObj)
|
|
{
|
|
m_project->info(currentObj, true); //forcing info window update
|
|
active=true;
|
|
}
|
|
if (fwbdebug) qDebug("/ObjectManipulator::info()");
|
|
}
|
|
|
|
|
|
void ObjectManipulator::restoreSelection(bool same_widget)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::restoreSelection same_widget=%d",same_widget);
|
|
|
|
select();
|
|
openObject( m_project->getOpenedEditor(), false);
|
|
}
|
|
|
|
void ObjectManipulator::editSelectedObject()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
if (obj==NULL) return;
|
|
editObject(obj);
|
|
}
|
|
|
|
bool ObjectManipulator::editObject(FWObject *obj)
|
|
{
|
|
if (!m_project->isEditorVisible()) m_project->showEditor();
|
|
return switchObjectInEditor(obj);
|
|
}
|
|
|
|
bool ObjectManipulator::switchObjectInEditor(FWObject *obj)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::switchObjectInEditor");
|
|
|
|
m_project->unselectRules();
|
|
|
|
if (!m_project->isEditorVisible()) return false;
|
|
|
|
if (!m_project->requestEditorOwnership(this,
|
|
obj,
|
|
ObjectEditor::optNone,
|
|
true))
|
|
return false;
|
|
|
|
select();
|
|
|
|
if (obj!=m_project->getOpenedEditor())
|
|
{
|
|
m_project->openEditor(obj);
|
|
currentObj=obj;
|
|
active=true;
|
|
openObject(obj); // position the tree so that obj is visible
|
|
}
|
|
return true; // successfully (re)opened obj in the editor
|
|
}
|
|
|
|
|
|
void ObjectManipulator::openObject(ObjectTreeViewItem *otvi,
|
|
bool register_in_history)
|
|
{
|
|
openObject(otvi->getFWObject(),register_in_history);
|
|
}
|
|
|
|
/* This method is called from the GroupObjectDialog when user double
|
|
* clicks on the object in a group, so first we should check if this
|
|
* object is shown in the tree and if not, find and open it.
|
|
*/
|
|
void ObjectManipulator::openObject(FWObject *obj, bool /*register_in_history*/)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::openObject obj=%s",
|
|
(obj)?obj->getName().c_str():"NULL");
|
|
|
|
if (obj==NULL) return;
|
|
|
|
raise();
|
|
FWObject *o=obj;
|
|
if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
|
|
|
|
ObjectTreeViewItem *otvi=allItems[o];
|
|
// this changes selection and thus calls slot slectionChanged
|
|
showObjectInTree(otvi);
|
|
|
|
m_objectManipulator->libs->setCurrentIndex( getIdxForLib( obj->getLibrary() ) );
|
|
updateCreateObjectMenu( obj->getLibrary() );
|
|
}
|
|
|
|
void ObjectManipulator::selectionChanged(QTreeWidgetItem *cur)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::selectionChanged");
|
|
|
|
QTreeWidget *qlv= getCurrentObjectTree();
|
|
if (qlv==NULL) return;
|
|
|
|
ObjectTreeViewItem* otvi=dynamic_cast<ObjectTreeViewItem*>(cur);
|
|
|
|
if (otvi==NULL) return;
|
|
|
|
FWObject *obj=otvi->getFWObject();
|
|
if (obj==NULL) return;
|
|
|
|
FWObject *o=obj;
|
|
// if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
|
|
|
|
if (history.empty() || otvi!=history.top().item() )
|
|
{
|
|
mw->m_mainWindow->backAction->setEnabled( true );
|
|
history.push( HistoryItem(otvi,o->getId().c_str()) );
|
|
}
|
|
|
|
currentObj = obj;
|
|
|
|
bool dupMenuItem=true;
|
|
bool moveMenuItem=true;
|
|
bool copyMenuItem=true;
|
|
bool pasteMenuItem=true;
|
|
bool delMenuItem=true;
|
|
bool newMenuItem=true;
|
|
bool inDeletedObjects = false;
|
|
|
|
getMenuState(false,
|
|
dupMenuItem,moveMenuItem,copyMenuItem,pasteMenuItem,
|
|
delMenuItem,newMenuItem,inDeletedObjects);
|
|
|
|
mw->m_mainWindow->editCopyAction->setEnabled(copyMenuItem);
|
|
mw->m_mainWindow->editDeleteAction->setEnabled(delMenuItem);
|
|
mw->m_mainWindow->editCutAction->setEnabled(copyMenuItem);
|
|
mw->m_mainWindow->editPasteAction->setEnabled(pasteMenuItem);
|
|
|
|
active=true;
|
|
|
|
/*
|
|
m_project->unselectRules();
|
|
if (m_project->validateAndSaveEditor())
|
|
{
|
|
//oe->selectionChanged(obj);
|
|
}
|
|
*/
|
|
info();
|
|
select();
|
|
}
|
|
|
|
/*
|
|
* I could use default value for the parameter register_in_history,
|
|
* but that caused problems when this method was used as a slot
|
|
*/
|
|
void ObjectManipulator::openObject(QTreeWidgetItem *item)
|
|
{
|
|
ObjectTreeViewItem *otvi=dynamic_cast<ObjectTreeViewItem*>(item);
|
|
openObject(otvi,true);
|
|
}
|
|
|
|
void ObjectManipulator::openObject(FWObject *obj)
|
|
{
|
|
openObject(obj,true);
|
|
}
|
|
|
|
void ObjectManipulator::showObjectInTree(ObjectTreeViewItem *otvi)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::showObjectInTree");
|
|
if (otvi==NULL) return;
|
|
|
|
ObjectTreeView* otv = otvi->getTree();
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::showObjectInTree current_tree_view=%p new_otv=%p",current_tree_view,otv);
|
|
|
|
otv->raise();
|
|
m_objectManipulator->widgetStack->setCurrentWidget(otv);
|
|
|
|
otvi->getTree()->clearSelection();
|
|
otvi->getTree()->scrollToItem( otvi );
|
|
otvi->getTree()->setCurrentItem( otvi );
|
|
otvi->setSelected( true );
|
|
}
|
|
|
|
void ObjectManipulator::invalidateDialog()
|
|
{
|
|
currentObj=NULL;
|
|
}
|
|
|
|
void ObjectManipulator::libChanged(int ln)
|
|
{
|
|
QTreeWidget *lv = idxToTrees[ln];
|
|
assert(lv!=NULL);
|
|
|
|
ObjectTreeViewItem *otvi=dynamic_cast<ObjectTreeViewItem*>(lv->currentItem());
|
|
|
|
if (otvi == NULL)
|
|
if (lv->invisibleRootItem()->childCount() > 0)
|
|
otvi = dynamic_cast<ObjectTreeViewItem*>(lv->invisibleRootItem()->child(0));
|
|
else
|
|
assert(FALSE);
|
|
|
|
currentObj=otvi->getFWObject();
|
|
showObjectInTree( otvi );
|
|
|
|
info();
|
|
|
|
updateCreateObjectMenu( idxToLibs[ln] );
|
|
return;
|
|
}
|
|
|
|
void ObjectManipulator::updateCreateObjectMenu(FWObject* lib)
|
|
{
|
|
bool f =
|
|
lib->getId()==STANDARD_LIB ||
|
|
lib->getId()==TEMPLATE_LIB ||
|
|
lib->getId()==DELETED_LIB ||
|
|
lib->isReadOnly();
|
|
|
|
m_objectManipulator->newButton->setEnabled( !f );
|
|
QAction *noa = (QAction*)(mw->findChild<QAction*>("newObjectAction"));
|
|
noa->setEnabled( !f );
|
|
}
|
|
|
|
void ObjectManipulator::back()
|
|
{
|
|
// if (!validateDialog()) return;
|
|
|
|
if (!history.empty())
|
|
{
|
|
history.pop();
|
|
|
|
/* skip objects that have been deleted */
|
|
while ( ! history.empty())
|
|
{
|
|
if (m_project->db()->findInIndex( history.top().id().toLatin1().constData() )!=NULL) break;
|
|
history.pop();
|
|
}
|
|
|
|
if (history.empty())
|
|
{
|
|
mw->m_mainWindow->backAction->setEnabled( false );
|
|
return;
|
|
}
|
|
|
|
openObject( history.top().item(), false );
|
|
|
|
if (m_project->isEditorVisible())
|
|
{
|
|
ObjectTreeViewItem *otvi=history.top().item();
|
|
switchObjectInEditor(otvi->getFWObject());
|
|
}
|
|
}
|
|
}
|
|
|
|
FWObject* ObjectManipulator::getCurrentLib()
|
|
{
|
|
return idxToLibs[ m_objectManipulator->libs->currentIndex() ];
|
|
}
|
|
|
|
ObjectTreeView* ObjectManipulator::getCurrentObjectTree()
|
|
{
|
|
return current_tree_view;
|
|
}
|
|
|
|
void ObjectManipulator::openLib(FWObject *obj)
|
|
{
|
|
openObject(obj->getLibrary(),false);
|
|
}
|
|
|
|
void ObjectManipulator::newObject()
|
|
{
|
|
// QToolButton *btn = (QToolButton*)(m_project->toolBar)->child("newObjectAction_action_button");
|
|
m_objectManipulator->newButton->showMenu();
|
|
}
|
|
|
|
FWObject* ObjectManipulator::createObject(const QString &objType,
|
|
const QString &objName,
|
|
FWObject *copyFrom)
|
|
{
|
|
if (!validateDialog()) return NULL;
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::createObject check 1");
|
|
|
|
FWObject *lib = getCurrentLib();
|
|
int i = 0;
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("lib: %s %s",lib->getName().c_str(), lib->getId().c_str());
|
|
qDebug("lib: isReadOnly=%d isLoaded=%d",
|
|
lib->isReadOnly(), m_project->getAddOnLibs()->isLoaded( lib->getName().c_str() ) );
|
|
qDebug("libs->count()=%d", m_objectManipulator->libs->count() );
|
|
}
|
|
|
|
while ( lib->getId()==STANDARD_LIB ||
|
|
lib->getId()==TEMPLATE_LIB ||
|
|
lib->getId()==DELETED_LIB ||
|
|
lib->isReadOnly() )
|
|
{
|
|
if (i>=m_objectManipulator->libs->count())
|
|
{
|
|
// if (fwbdebug)
|
|
// qDebug("ObjectManipulator::createObject return NULL");
|
|
// return NULL;
|
|
lib = getCurrentLib();
|
|
break;
|
|
}
|
|
|
|
lib= idxToLibs[i];
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("i=%d",i);
|
|
qDebug("lib: %s %s",lib->getName().c_str(), lib->getId().c_str());
|
|
qDebug("lib: isReadOnly=%d isLoaded=%d",
|
|
lib->isReadOnly(), m_project->getAddOnLibs()->isLoaded( lib->getName().c_str() ) );
|
|
}
|
|
i++;
|
|
}
|
|
|
|
FWObject *parent=m_project->getStandardSlotForObject(lib, objType);
|
|
if (parent==NULL)
|
|
{
|
|
|
|
QMessageBox::warning(this,"Firewall Builder",
|
|
QObject::tr(
|
|
"Type '%1': new object can not be created because\n"
|
|
"corresponding branch is missing in the object tree.\n"
|
|
"Please repair the tree using command 'fwbedit -s -f file.fwb'.")
|
|
.arg(objType),
|
|
"&Continue", QString::null, QString::null,
|
|
0, 1 );
|
|
|
|
|
|
return NULL;
|
|
}
|
|
return actuallyCreateObject(parent,objType,objName,copyFrom);
|
|
}
|
|
|
|
FWObject* ObjectManipulator::createObject(FWObject *parent,
|
|
const QString &objType,
|
|
const QString &objName,
|
|
FWObject *copyFrom)
|
|
{
|
|
if (!validateDialog()) return NULL;
|
|
|
|
FWObject *lib = getCurrentLib();
|
|
int i = 0;
|
|
|
|
assert(parent!=NULL);
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("ObjectManipulator::createObject 2: parent=%s",
|
|
parent->getName().c_str());
|
|
qDebug("ObjectManipulator::createObject 2: objType=%s objName=%s",
|
|
objType.toLatin1().constData(), objName.toLatin1().constData());
|
|
}
|
|
|
|
while ( lib->getId()==STANDARD_LIB ||
|
|
lib->getId()==TEMPLATE_LIB ||
|
|
lib->getId()==DELETED_LIB ||
|
|
lib->isReadOnly() )
|
|
{
|
|
if (i >= m_objectManipulator->libs->count())
|
|
{
|
|
lib=getCurrentLib();
|
|
break;
|
|
}
|
|
lib= idxToLibs[i];
|
|
i++;
|
|
}
|
|
|
|
if (parent==NULL) parent=lib;
|
|
|
|
return actuallyCreateObject(parent,objType,objName,copyFrom);
|
|
}
|
|
|
|
|
|
FWObject* ObjectManipulator::copyObj2Tree(const QString &objType, const QString &objName,
|
|
libfwbuilder::FWObject *copyFrom, FWObject *parent, bool askLib)
|
|
{
|
|
if (!validateDialog()) return NULL;
|
|
ids.clear();
|
|
return copyObjWithDeep(copyFrom);
|
|
}
|
|
|
|
libfwbuilder::FWObject * ObjectManipulator::copyObjWithDeep(libfwbuilder::FWObject *copyFrom)
|
|
{
|
|
|
|
if (copyFrom==NULL)
|
|
return NULL;
|
|
FWObject *nobj= copyFrom;
|
|
if (nobj->getId()!="")
|
|
{
|
|
if (ids.contains(nobj->getId().c_str()))
|
|
{
|
|
|
|
return nobj;
|
|
}
|
|
else
|
|
{
|
|
ids.insert(nobj->getId().c_str());
|
|
}
|
|
}
|
|
//nobj->duplicate(copyFrom,false);
|
|
FWReference * ref = FWReference::cast(nobj);
|
|
if (ref!=NULL)
|
|
{
|
|
FWObject * obj = copyObjWithDeep(ref->getPointer());
|
|
return ref ;
|
|
}
|
|
|
|
Group * group = Group::cast(nobj);
|
|
if (group!=NULL)
|
|
{
|
|
|
|
for (list<FWObject*>::iterator i=nobj->begin() ; i!=nobj->end(); ++i)
|
|
{
|
|
// qDebug((*i)->getTypeName().c_str());
|
|
// qDebug((*i)->getName().c_str());
|
|
copyObjWithDeep(*i);
|
|
}
|
|
|
|
//return group;
|
|
}
|
|
Firewall * fw = Firewall::cast(nobj);
|
|
if (fw!=NULL)
|
|
{
|
|
for (libfwbuilder::FWObject::iterator i=fw->begin(); i!=fw->end(); i++)
|
|
{
|
|
|
|
RuleSet *rule = RuleSet::cast(*i);
|
|
if (rule==NULL)
|
|
continue;
|
|
copyObjWithDeep(rule);
|
|
//FWOptions *ropt = rule->getOptionsObject();
|
|
//if (ropt)
|
|
// extRefs.push_back(ropt);
|
|
}
|
|
}
|
|
RuleSet * ruleset = RuleSet::cast(nobj);
|
|
if (ruleset!=NULL)
|
|
{
|
|
|
|
for (list<FWObject*>::iterator i=ruleset->begin() ; i!=ruleset->end(); ++i)
|
|
{
|
|
copyObjWithDeep(*i);
|
|
}
|
|
}
|
|
|
|
Rule * rule = Rule::cast(nobj);
|
|
if (rule!=NULL)
|
|
{
|
|
for (int col =0; col < 5; col++)
|
|
{
|
|
RuleElement *re = m_project->getRE(rule, col);
|
|
if (!re) continue;
|
|
copyObjWithDeep(re);
|
|
}
|
|
return rule;
|
|
}
|
|
FWObject * lib = getCurrentLib();
|
|
|
|
if (lib->getRoot()->getById(nobj->getId(),true)==NULL)
|
|
{
|
|
FWObject *par = m_project->getStandardSlotForObject(lib, nobj->getTypeName().c_str());
|
|
FWObject *no = pasteTo (par, nobj, false, false, false);
|
|
if (no && Firewall::isA(no))
|
|
{
|
|
m_project->addFirewallToList(no);
|
|
m_project->showFirewall(no);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
FWObject* ObjectManipulator::actuallyCreateObject(FWObject *parent,
|
|
const QString &objType,
|
|
const QString &objName,
|
|
FWObject *copyFrom)
|
|
{
|
|
if (!isTreeReadWrite(this, parent)) return NULL;
|
|
FWObject *nobj = m_project->db()->create(objType.toLatin1().constData());
|
|
assert(nobj!=NULL);
|
|
|
|
if (copyFrom!=NULL) nobj->duplicate(copyFrom,true);
|
|
if (nobj->isReadOnly()) nobj->setReadOnly(false);
|
|
|
|
nobj->setName( string(objName.toUtf8().constData()) );
|
|
makeNameUnique(parent,nobj);
|
|
|
|
parent->add(nobj);
|
|
insertSubtree(allItems[parent], nobj);
|
|
|
|
m_project->db()->setDirty(true);
|
|
return nobj;
|
|
}
|
|
|
|
void ObjectManipulator::newLibrary()
|
|
{
|
|
if (!validateDialog()) return;
|
|
|
|
FWObject *nlib = m_project->createNewLibrary(m_project->db());
|
|
|
|
addTreePage( nlib );
|
|
|
|
openObject( nlib );
|
|
editObject(nlib);
|
|
}
|
|
|
|
void ObjectManipulator::newFirewall()
|
|
{
|
|
newFirewallDialog *nfd=new newFirewallDialog();
|
|
if (m_project->isEditorVisible()) m_project->hideEditor();
|
|
nfd->exec();
|
|
FWObject *o = nfd->getNewFirewall();
|
|
delete nfd;
|
|
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
|
|
m_project->addFirewallToList(o);
|
|
m_project->showFirewall(o);
|
|
// updateLastModifiedTimestampForAllFirewalls(o);
|
|
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newHost()
|
|
{
|
|
newHostDialog *nhd=new newHostDialog();
|
|
if (m_project->isEditorVisible()) m_project->hideEditor();
|
|
nhd->exec();
|
|
FWObject *o = nhd->getNewHost();
|
|
delete nhd;
|
|
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newInterface()
|
|
{
|
|
if ( currentObj->isReadOnly() ) return;
|
|
|
|
FWObject *i=NULL;
|
|
|
|
if (Host::isA(currentObj) || Firewall::isA(currentObj))
|
|
i=createObject(currentObj,Interface::TYPENAME,tr("New Interface"));
|
|
|
|
if (Interface::isA(currentObj))
|
|
i=createObject(currentObj->getParent(),Interface::TYPENAME,tr("New Interface"));
|
|
|
|
if (i==NULL) return;
|
|
|
|
#ifdef USE_INTERFACE_POLICY
|
|
if (Firewall::isA(i->getParent())) i->add(new InterfacePolicy());
|
|
#endif
|
|
|
|
openObject( i );
|
|
|
|
if (Firewall::isA(i->getParent())) m_project->showFirewall(i->getParent());
|
|
updateLastModifiedTimestampForAllFirewalls(i);
|
|
|
|
editObject(i);
|
|
}
|
|
|
|
void ObjectManipulator::newNetwork()
|
|
{
|
|
FWObject *o=createObject(Network::TYPENAME,tr("New Network"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newAddress()
|
|
{
|
|
if ( currentObj->isReadOnly() ) return;
|
|
|
|
FWObject *o;
|
|
/*
|
|
* Oleg reports that his expectation was that "New Address" should
|
|
* always create an address object even if current selected object in
|
|
* the tree is an interface. I tend to agree with him, this was a
|
|
* usability issue because behavior of the program was different
|
|
* depending on which object was selected in the tree. I am changing
|
|
* it and will make it so "New Address" will always create a new
|
|
* Address object uner Objects/Addresses. Interface address can be
|
|
* created using context pop-up menu.
|
|
* 12/19/04 --vk
|
|
*/
|
|
o=createObject(IPv4::TYPENAME,tr("New Address"));
|
|
|
|
#if 0
|
|
if (Interface::isA(currentObj))
|
|
{
|
|
Interface *intf = Interface::cast(currentObj);
|
|
if (intf &&
|
|
(intf->isDyn() || intf->isUnnumbered() || intf->isBridgePort())
|
|
) return;
|
|
QString iname=QString("%1:%2:ip")
|
|
.arg(QString::fromUtf8(currentObj->getParent()->getName().c_str()))
|
|
.arg(QString::fromUtf8(currentObj->getName().c_str()));
|
|
o=createObject(currentObj, IPv4::TYPENAME, iname);
|
|
}
|
|
else
|
|
{
|
|
o=createObject(IPv4::TYPENAME,tr("New Address"));
|
|
}
|
|
#endif
|
|
|
|
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newDNSName()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(DNSName::TYPENAME,tr("New DNS Name"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newAddressTable()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(AddressTable::TYPENAME,tr("New Address Table"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newInterfaceAddress()
|
|
{
|
|
if ( currentObj->isReadOnly() ) return;
|
|
|
|
if (Interface::isA(currentObj))
|
|
{
|
|
Interface *intf = Interface::cast(currentObj);
|
|
if (intf &&
|
|
(intf->isDyn() || intf->isUnnumbered() || intf->isBridgePort())
|
|
) return;
|
|
QString iname=QString("%1:%2:ip")
|
|
.arg(QString::fromUtf8(currentObj->getParent()->getName().c_str()))
|
|
.arg(QString::fromUtf8(currentObj->getName().c_str()));
|
|
FWObject *o=createObject(currentObj, IPv4::TYPENAME, iname);
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
updateLastModifiedTimestampForAllFirewalls(o);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newTagService()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(TagService::TYPENAME,tr("New TagService"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
void ObjectManipulator::newPhysicalAddress()
|
|
{
|
|
if ( currentObj->isReadOnly() ) return;
|
|
|
|
if (Interface::isA(currentObj))
|
|
{
|
|
Interface *intf = Interface::cast(currentObj);
|
|
if (intf->getByType(physAddress::TYPENAME).empty())
|
|
{
|
|
QString iname=QString("%1:%2:mac")
|
|
.arg(QString::fromUtf8(currentObj->getParent()->getName().c_str()))
|
|
.arg(QString::fromUtf8(currentObj->getName().c_str()));
|
|
FWObject *o=createObject(currentObj,physAddress::TYPENAME,iname);
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
updateLastModifiedTimestampForAllFirewalls(o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newAddressRange()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(AddressRange::TYPENAME,tr("New Address Range"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newObjectGroup()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(ObjectGroup::TYPENAME,tr("New Object Group"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
|
|
void ObjectManipulator::newCustom()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(CustomService::TYPENAME,tr("New Custom Service"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newIP()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(IPService::TYPENAME,tr("New IP Service"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newICMP()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(ICMPService::TYPENAME,tr("New ICMP Service"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newTCP()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(TCPService::TYPENAME,tr("New TCP Service"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newUDP()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(UDPService::TYPENAME,tr("New UDP Service"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::newServiceGroup()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(ServiceGroup::TYPENAME,tr("New Service Group"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
|
|
void ObjectManipulator::newInterval()
|
|
{
|
|
FWObject *o;
|
|
o=createObject(Interval::TYPENAME,tr("New Time Interval"));
|
|
if (o!=NULL)
|
|
{
|
|
openObject(o);
|
|
editObject(o);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool ObjectManipulator::validateDialog()
|
|
{
|
|
if (currentObj==NULL) return true;
|
|
if (!m_project->isEditorVisible()) return true;
|
|
return m_project->validateAndSaveEditor();
|
|
}
|
|
|
|
void ObjectManipulator::select()
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::select()");
|
|
|
|
if (currentObj==NULL) return;
|
|
ObjectTreeViewItem *otvi=allItems[currentObj];
|
|
if (otvi)
|
|
{
|
|
otvi->setSelected(true);
|
|
active=true;
|
|
otvi->treeWidget()->setFocus();
|
|
otvi->treeWidget()->update();
|
|
}
|
|
|
|
m_project->updateRuleSetViewSelection();
|
|
|
|
if (fwbdebug)
|
|
qDebug("/ObjectManipulator::select()");
|
|
}
|
|
|
|
void ObjectManipulator::unselect()
|
|
{
|
|
if (currentObj==NULL) return;
|
|
|
|
for (int i=0; i<m_objectManipulator->libs->count(); i++)
|
|
idxToTrees[i]->clearSelection();
|
|
|
|
active=false;
|
|
}
|
|
|
|
bool ObjectManipulator::isSelected()
|
|
{
|
|
return active;
|
|
}
|
|
|
|
list<Firewall *> ObjectManipulator::findFirewallsForObject(FWObject *o)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("ObjectManipulator::findFirewallsForObject");
|
|
|
|
list<Firewall *> fws;
|
|
set<FWObject *> resset;
|
|
QTime tt;
|
|
tt.start();
|
|
FWObject *f=o;
|
|
while (f!=NULL && !Firewall::isA(f)) f=f->getParent();
|
|
if (f) fws.push_back(Firewall::cast(f));
|
|
m_project->db()->findWhereUsed(o,m_project->db(),resset);
|
|
|
|
set<FWObject *>::iterator i=resset.begin();
|
|
for ( ;i!=resset.end();++i)
|
|
{
|
|
RuleElement *re=RuleElement::cast(*i);
|
|
if (re==NULL) continue;
|
|
|
|
Rule *r=Rule::cast(re->getParent());
|
|
if (r && !r->isDisabled())
|
|
{
|
|
f=r;
|
|
while (f!=NULL && !Firewall::isA(f)) f=f->getParent();
|
|
if (f && std::find(fws.begin(),fws.end(),f)==fws.end())
|
|
fws.push_back(Firewall::cast(f));
|
|
}
|
|
}
|
|
|
|
if (fwbdebug)
|
|
qDebug(QString("Program spent %1 ms searching for firewalls.")
|
|
.arg(tt.elapsed()).toAscii().constData());
|
|
|
|
return fws;
|
|
}
|
|
|
|
void ObjectManipulator::updateLastModifiedTimestampForOneFirewall(FWObject *o)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::updateLastModifiedTimestampForOneFirewall");
|
|
|
|
if (o==NULL) return;
|
|
|
|
Firewall *f = Firewall::cast(o);
|
|
if (f==NULL) return;
|
|
|
|
f->updateLastModifiedTimestamp();
|
|
getCurrentObjectTree()->updateTreeItems ();
|
|
info();
|
|
}
|
|
|
|
|
|
void ObjectManipulator::updateLastModifiedTimestampForAllFirewalls(FWObject *o)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::updateLastModifiedTimestampForAllFirewalls");
|
|
|
|
if (o==NULL) return;
|
|
|
|
QStatusBar *sb = mw->statusBar();
|
|
sb->showMessage( tr("Searching for firewalls affected by the change...") );
|
|
|
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100);
|
|
|
|
if (fwbdebug) qDebug("ObjectManipulator::updateLastModifiedTimestampForAllFirewalls: setOverrideCursor");
|
|
QApplication::setOverrideCursor(QCursor( Qt::WaitCursor));
|
|
|
|
list<Firewall *> fws = findFirewallsForObject(o);
|
|
if (fws.size())
|
|
{
|
|
Firewall *f;
|
|
for (list<Firewall *>::iterator i=fws.begin();
|
|
i!=fws.end();
|
|
++i)
|
|
{
|
|
f=*i;
|
|
f->updateLastModifiedTimestamp();
|
|
}
|
|
|
|
getCurrentObjectTree()->updateTreeItems ();
|
|
info();
|
|
}
|
|
if (fwbdebug) qDebug("ObjectManipulator::updateLastModifiedTimestampForAllFirewalls: restoreOverrideCursor");
|
|
QApplication::restoreOverrideCursor();
|
|
sb->clearMessage();
|
|
|
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100);
|
|
}
|
|
|
|
void ObjectManipulator::updateLastInstalledTimestamp(FWObject *o)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::updateLastInstalledTimestamp");
|
|
if (o==NULL) return;
|
|
Firewall * f=(Firewall *)o;
|
|
if (f!=NULL)
|
|
{
|
|
bool visualUpdate=f->needsInstall();
|
|
f->updateLastInstalledTimestamp();
|
|
if (visualUpdate)
|
|
{
|
|
getCurrentObjectTree()->updateTreeItems ();
|
|
}
|
|
info();
|
|
}
|
|
}
|
|
void ObjectManipulator::updateLastCompiledTimestamp(FWObject *o)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::updateLastCompiledTimestamp");
|
|
|
|
if (o==NULL) return;
|
|
Firewall * f=(Firewall *)o;
|
|
if (f!=NULL)
|
|
{
|
|
f->updateLastCompiledTimestamp();
|
|
info();
|
|
}
|
|
}
|
|
|
|
void ObjectManipulator::simulateInstall()
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::simulateInstall");
|
|
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
Firewall *fw;
|
|
|
|
vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
|
|
for (vector<FWObject*>::iterator i=so.begin(); i!=so.end(); ++i)
|
|
{
|
|
fw= Firewall::cast( *i );
|
|
if (fw!=NULL)
|
|
{
|
|
fw->updateLastCompiledTimestamp();
|
|
fw->updateLastInstalledTimestamp();
|
|
}
|
|
}
|
|
getCurrentObjectTree()->updateTreeItems ();
|
|
|
|
}
|
|
|
|
void ObjectManipulator::findAllFirewalls (list<Firewall *> &fws)
|
|
{
|
|
if (fwbdebug) qDebug("ObjectManipulator::findAllFirewalls");
|
|
|
|
std::list<FWObject*> fwlist;
|
|
findByObjectType(m_project->db(),Firewall::TYPENAME,fwlist);
|
|
for (list<FWObject*>::iterator m=fwlist.begin(); m!=fwlist.end(); m++)
|
|
fws.push_back( Firewall::cast(*m) );
|
|
}
|
|
|
|
FWObject* ObjectManipulator::getSelectedObject()
|
|
{
|
|
return currentObj;
|
|
}
|
|
|
|
void ObjectManipulator::findWhereUsedSlot()
|
|
{
|
|
if (getCurrentObjectTree()->getNumSelected()==0) return;
|
|
|
|
FWObject *obj=getCurrentObjectTree()->getSelectedObjects().front();
|
|
if (obj==NULL) return;
|
|
m_project->findWhereUsed(obj);
|
|
|
|
}
|
|
|
|
void ObjectManipulator::reopenCurrentItemParent()
|
|
{
|
|
QTreeWidgetItem *itm = current_tree_view->currentItem();
|
|
if (itm)
|
|
itm = itm->parent();
|
|
if (!itm)
|
|
return;
|
|
itm->parent()->setExpanded(false);
|
|
itm->parent()->setExpanded(true);
|
|
|
|
current_tree_view->scrollToItem(itm);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|