mirror of
https://github.com/fwbuilder/fwbuilder
synced 2026-09-12 08:02:00 +02:00
1459 lines
44 KiB
C++
1459 lines
44 KiB
C++
/*
|
|
|
|
Firewall Builder
|
|
|
|
Copyright (C) 2008 NetCitadel, LLC
|
|
|
|
Author: Vadim Kurland vadim@fwbuilder.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 "global.h"
|
|
#include "utils.h"
|
|
#include "utils_no_qt.h"
|
|
|
|
#include "instDialog.h"
|
|
#include "FirewallInstaller.h"
|
|
#include "FWBSettings.h"
|
|
#include "FWWindow.h"
|
|
#include "InstallFirewallViewItem.h"
|
|
#include "instOptionsDialog.h"
|
|
#include "instBatchOptionsDialog.h"
|
|
#include "UserWorkflow.h"
|
|
#include "FirewallCodeViewer.h"
|
|
|
|
#include <qcheckbox.h>
|
|
#include <qlineedit.h>
|
|
#include <qtextedit.h>
|
|
#include <qtimer.h>
|
|
#include <qfiledialog.h>
|
|
#include <qpushbutton.h>
|
|
#include <qlabel.h>
|
|
#include <qprogressbar.h>
|
|
#include <qprocess.h>
|
|
#include <qapplication.h>
|
|
#include <qeventloop.h>
|
|
#include <qfile.h>
|
|
#include <qdir.h>
|
|
#include <qmessagebox.h>
|
|
#include <qspinbox.h>
|
|
#include <qgroupbox.h>
|
|
#include <qcolor.h>
|
|
#include <qtablewidget.h>
|
|
#include <qtextcodec.h>
|
|
#include <qfileinfo.h>
|
|
#include <qtextstream.h>
|
|
#include <qpixmapcache.h>
|
|
|
|
#include <QPixmap>
|
|
#include <QDateTime>
|
|
#include <QTableWidget>
|
|
#include <QTableWidgetItem>
|
|
#include <QTreeWidgetItemIterator>
|
|
#include <QTextBlockFormat>
|
|
#include <QBrush>
|
|
#include <QTextFormat>
|
|
#include <QtDebug>
|
|
#include <QTime>
|
|
|
|
#include "fwbuilder/Resources.h"
|
|
#include "fwbuilder/FWObjectDatabase.h"
|
|
#include "fwbuilder/Library.h"
|
|
#include "fwbuilder/Firewall.h"
|
|
#include "fwbuilder/Cluster.h"
|
|
#include "fwbuilder/XMLTools.h"
|
|
#include "fwbuilder/Interface.h"
|
|
#include "fwbuilder/Management.h"
|
|
#include "fwbuilder/StateSyncClusterGroup.h"
|
|
|
|
#ifndef _WIN32
|
|
# include <unistd.h> // for access(2) and getdomainname
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
|
|
|
|
using namespace std;
|
|
using namespace libfwbuilder;
|
|
|
|
void instDialog::enableStopButton()
|
|
{
|
|
currentStopButton->setText(tr("Stop"));
|
|
currentStopButton->setEnabled(true);
|
|
}
|
|
|
|
void instDialog::disableStopButton()
|
|
{
|
|
currentStopButton->setEnabled(false);
|
|
}
|
|
|
|
bool instDialog::checkIfNeedToCompile(Firewall *fw)
|
|
{
|
|
return (fw->needsCompile() && !fw->getInactive());
|
|
}
|
|
|
|
bool instDialog::checkIfNeedToInstall(Firewall *fw)
|
|
{
|
|
return (fw->needsInstall() && !fw->getInactive());
|
|
}
|
|
|
|
QTreeWidgetItem* instDialog::createTreeItem(QTreeWidgetItem* parent,
|
|
Firewall *fw)
|
|
{
|
|
QTreeWidgetItem* item;
|
|
QStringList sl;
|
|
sl.push_back(QString::fromUtf8(fw->getName().c_str()));
|
|
|
|
if (parent)
|
|
item = new QTreeWidgetItem(parent, sl);
|
|
else
|
|
item = new QTreeWidgetItem(sl);
|
|
|
|
QString icn_filename = (":/Icons/" + fw->getTypeName() + "/icon").c_str();
|
|
QPixmap pm;
|
|
if ( ! QPixmapCache::find(icn_filename, pm))
|
|
{
|
|
pm.load(icn_filename);
|
|
QPixmapCache::insert(icn_filename, pm);
|
|
}
|
|
item->setIcon(0, QIcon(pm));
|
|
|
|
item->setData(0, Qt::UserRole, QVariant(fw->getId()));
|
|
|
|
// Mark cluster members
|
|
// If parent!=NULL, new tree item corresponds to the cluster member
|
|
item->setData(1, Qt::UserRole, QVariant(parent!=NULL));
|
|
|
|
// it is useful to know how many members does this cluster have. If this is
|
|
// not a cluster, store 0
|
|
list<Firewall*> members;
|
|
if (Cluster::isA(fw))
|
|
Cluster::cast(fw)->getMembersList(members);
|
|
int num_members = members.size();
|
|
|
|
item->setData(2, Qt::UserRole, QVariant(num_members));
|
|
|
|
// item->setCheckState(COMPILE_CHECKBOX_COLUMN, checkIfNeedToCompile(fw)?Qt::Checked:Qt::Unchecked);
|
|
// if (!compile_only)
|
|
// item->setCheckState(INSTALL_CHECKBOX_COLUMN, checkIfNeedToInstall(fw)?Qt::Checked:Qt::Unchecked);
|
|
|
|
return item;
|
|
}
|
|
|
|
void instDialog::setFlags(QTreeWidgetItem* item)
|
|
{
|
|
int obj_id = item->data(0, Qt::UserRole).toInt();
|
|
Firewall *fw = Firewall::cast(project->db()->findInIndex(obj_id));
|
|
QTreeWidgetItem* parent = item->parent();
|
|
|
|
time_t lm = fw->getInt("lastModified");
|
|
time_t lc = fw->getInt("lastCompiled");
|
|
time_t li = fw->getInt("lastInstalled");
|
|
QDateTime dt;
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug() << "instDialog::setFlags"
|
|
<< item->text(0)
|
|
<< "parent=" << parent
|
|
<< "fw=" << fw
|
|
<< "Firewall::isA(fw)=" << Firewall::isA(fw)
|
|
<< "lm=" << lm
|
|
<< "lc=" << lc
|
|
<< "li=" << li
|
|
<< "compile_only=" << compile_only;
|
|
qDebug() << "fw->needsCompile()" << fw->needsCompile()
|
|
<< "checkIfNeedToCompile(fw)=" << checkIfNeedToCompile(fw);
|
|
}
|
|
|
|
// need to skip the secondary cluster members if platform only
|
|
// allows installations on the primary (e.g. PIX). Note that
|
|
// platform attribute must be the same in the cluster and member
|
|
// firewalls objects. See #998
|
|
|
|
string platform = fw->getStr("platform");
|
|
bool install_only_on_primary_member = Resources::getTargetCapabilityBool(
|
|
platform, "install_only_on_primary");
|
|
|
|
Cluster *cluster = NULL;
|
|
FWObject *master_interface = NULL;
|
|
|
|
if (parent)
|
|
{
|
|
int obj_id = parent->data(0, Qt::UserRole).toInt();
|
|
cluster = Cluster::cast(project->db()->findInIndex(obj_id));
|
|
if (cluster)
|
|
{
|
|
FWObject *state_sync_group =
|
|
cluster->getFirstByType(StateSyncClusterGroup::TYPENAME);
|
|
// use state sync group to find which member firewall is
|
|
// master. This is only needed for platforms that install
|
|
// only on master (PIX at this time)
|
|
if (state_sync_group)
|
|
{
|
|
string master_id = state_sync_group->getStr("master_iface");
|
|
for (FWObjectTypedChildIterator grp_it =
|
|
state_sync_group->findByType(FWObjectReference::TYPENAME);
|
|
grp_it != grp_it.end(); ++grp_it)
|
|
{
|
|
FWObject *iface = FWObjectReference::getObject(*grp_it);
|
|
if (FWObjectDatabase::getStringId(iface->getId()) == master_id)
|
|
{
|
|
master_interface = iface;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Real firewalls get checkbox for install
|
|
if (Firewall::isA(fw))
|
|
{
|
|
bool checked = false;
|
|
|
|
if (!compile_only)
|
|
{
|
|
checked = checkIfNeedToInstall(fw);
|
|
if (cluster)
|
|
{
|
|
// override if checkIfNeedToCompile() is true for the
|
|
// parent cluster.
|
|
if (checkIfNeedToCompile(cluster))
|
|
{
|
|
checked = true;
|
|
}
|
|
}
|
|
item->setCheckState(INSTALL_CHECKBOX_COLUMN,
|
|
checked?Qt::Checked:Qt::Unchecked);
|
|
|
|
// If this platform requires installation only on
|
|
// the master, disable and uncheck checkbox for the standby.
|
|
if (install_only_on_primary_member && master_interface != NULL)
|
|
{
|
|
QString txt = item->text(0);
|
|
if (master_interface->isChildOf(fw))
|
|
{
|
|
// Master
|
|
item->setText(0, QString("%1 (master)").arg(txt));
|
|
} else
|
|
{
|
|
// Standby
|
|
item->setText(0, QString("%1 (standby)").arg(txt));
|
|
item->setCheckState(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked);
|
|
item->setFlags(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cluster==NULL)
|
|
{
|
|
// we are adding firewall that is not cluster member, it
|
|
// needs "compile" checkbox
|
|
checked = checkIfNeedToCompile(fw);
|
|
item->setCheckState(COMPILE_CHECKBOX_COLUMN,
|
|
checked?Qt::Checked:Qt::Unchecked);
|
|
}
|
|
}
|
|
|
|
int num_members = 0;
|
|
// Clusters only get checkbox for compile, and only if they have members.
|
|
if (Cluster::isA(fw))
|
|
{
|
|
list<Firewall*> members;
|
|
Cluster::cast(fw)->getMembersList(members);
|
|
num_members = members.size();
|
|
if (num_members)
|
|
{
|
|
bool checked = checkIfNeedToCompile(fw);
|
|
item->setCheckState(COMPILE_CHECKBOX_COLUMN,
|
|
checked?Qt::Checked:Qt::Unchecked);
|
|
}
|
|
}
|
|
|
|
dt.setTime_t(lm);
|
|
item->setText(LAST_MODIFIED_COLUMN, (lm)?dt.toString():QString("Never"));
|
|
|
|
dt.setTime_t(lc);
|
|
item->setText(LAST_COMPILED_COLUMN, (lc)?dt.toString():QString("Never"));
|
|
|
|
dt.setTime_t(li);
|
|
item->setText(LAST_INSTALLED_COLUMN, (li)?dt.toString():QString("Never"));
|
|
}
|
|
|
|
/*
|
|
* The following color and font manipulations are subject to QT bug
|
|
* http://trolltech.no/developer/task-tracker/index_html?method=entry&id=212207
|
|
*
|
|
* This requires QT 4.4.1 or 4.3
|
|
*/
|
|
void instDialog::setSuccessState(QTreeWidgetItem *item)
|
|
{
|
|
QBrush b = item->foreground(1);
|
|
b.setColor(Qt::darkGreen);
|
|
item->setForeground(1,b);
|
|
item->setForeground(0,b);
|
|
|
|
QFont f = item->font(1);
|
|
f.setBold(true);
|
|
item->setFont(1,f);
|
|
item->setFont(0,f);
|
|
}
|
|
|
|
void instDialog::setFailureState(QTreeWidgetItem *item)
|
|
{
|
|
QBrush b = item->foreground(1);
|
|
b.setColor(Qt::darkRed);
|
|
item->setForeground(1,b);
|
|
item->setForeground(0,b);
|
|
|
|
QFont f = item->font(1);
|
|
f.setBold(true);
|
|
item->setFont(1,f);
|
|
item->setFont(0,f);
|
|
}
|
|
|
|
void instDialog::setErrorState(QTreeWidgetItem *item)
|
|
{
|
|
QBrush b = item->foreground(1);
|
|
b.setColor(Qt::darkRed);
|
|
item->setForeground(1,b);
|
|
item->setForeground(0,b);
|
|
|
|
QFont f = item->font(1);
|
|
f.setBold(true);
|
|
item->setFont(1,f);
|
|
item->setFont(0,f);
|
|
}
|
|
|
|
void instDialog::setInProcessState(QTreeWidgetItem *item)
|
|
{
|
|
QBrush b = item->foreground(1);
|
|
b.setColor(Qt::black);
|
|
item->setForeground(1,b);
|
|
item->setForeground(0,b);
|
|
|
|
QFont f = item->font(1);
|
|
f.setBold(true);
|
|
item->setFont(1,f);
|
|
item->setFont(0,f);
|
|
}
|
|
|
|
void instDialog::opSuccess(Firewall *fw)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::opSuccess fw=" << fw->getName().c_str();
|
|
|
|
compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_SUCCESS;
|
|
QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
|
|
if (itm)
|
|
{
|
|
itm->setText(1,tr("Success"));
|
|
setSuccessState(itm);
|
|
}
|
|
currentLabel->setText("");
|
|
|
|
if (installer)
|
|
wfl->registerFlag(UserWorkflow::INSTALL_SUCCESS, true);
|
|
}
|
|
|
|
void instDialog::opError(Firewall *fw)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::opError fw=" << fw->getName().c_str();
|
|
|
|
compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_ERROR;
|
|
QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
|
|
if (itm)
|
|
{
|
|
itm->setText(1, tr("Error"));
|
|
setErrorState(itm);
|
|
}
|
|
currentLabel->setText("");
|
|
}
|
|
|
|
void instDialog::opCancelled(Firewall *fw)
|
|
{
|
|
compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_ERROR;
|
|
QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
|
|
// itm can be NULL, for example when we install to PIX cluster
|
|
// where we skip one of the members
|
|
if (itm)
|
|
{
|
|
itm ->setText(1, tr("Cancelled"));
|
|
setErrorState(itm);
|
|
}
|
|
currentLabel->setText("");
|
|
}
|
|
|
|
void instDialog::nextClicked()
|
|
{
|
|
if (currentPage() == CHOOSE_OBJECTS)
|
|
{
|
|
page_1_op = INST_DLG_COMPILE;
|
|
showPage(COMPILE_INSTALL);
|
|
return;
|
|
}
|
|
|
|
if (currentPage() == COMPILE_INSTALL &&
|
|
(page_1_op == INST_DLG_COMPILE || page_1_op == INST_DLG_INSPECT))
|
|
{
|
|
// clicking "Next" on page 1 (compile/install) changes
|
|
// contents of the same page
|
|
page_1_op = INST_DLG_INSTALL;
|
|
showPage(COMPILE_INSTALL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void instDialog::backClicked()
|
|
{
|
|
if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_COMPILE)
|
|
{
|
|
// clicking "Back" on page 1 in mode "compile" returns to page 0
|
|
page_1_op = INST_DLG_COMPILE;
|
|
showPage(CHOOSE_OBJECTS);
|
|
return;
|
|
}
|
|
|
|
if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_INSTALL)
|
|
{
|
|
// clicking "Back" on page 1 in mode "install" changes
|
|
// contents of the same page. Ideally, I would like to be
|
|
// able to move back from "install" mode to "compile" mode
|
|
// without recompiling everything. This is impossible in the
|
|
// current implementation because we reuse the same widgets on
|
|
// the page. This will be possible when "install" becomes its
|
|
// own page of the wizard.
|
|
|
|
// page_1_op = INST_DLG_COMPILE;
|
|
// showPage(COMPILE_INSTALL);
|
|
return;
|
|
}
|
|
|
|
if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_INSPECT)
|
|
{
|
|
page_1_op = INST_DLG_COMPILE;
|
|
showPage(COMPILE_INSTALL);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void instDialog::inspectFiles()
|
|
{
|
|
page_1_op = INST_DLG_INSPECT;
|
|
showPage(COMPILE_INSTALL);
|
|
}
|
|
|
|
void instDialog::prepareInstConf(Firewall *)
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::prepareInstConf");
|
|
}
|
|
|
|
void instDialog::storeInstallerOptions()
|
|
{
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/savediff",cnf.save_diff);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/saveStandby",cnf.saveStandby);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/dryrun" ,cnf.dry_run);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/quiet", cnf.quiet);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/verbose", cnf.verbose);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/stripComments", cnf.stripComments);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/compressScript", cnf.compressScript);
|
|
st->setValue(SETTINGS_PATH_PREFIX"/Installer/copyFWB", cnf.copyFWB);
|
|
}
|
|
|
|
void instDialog::summary()
|
|
{
|
|
QStringList str;
|
|
|
|
str.append(QObject::tr("Summary:"));
|
|
str.append(QObject::tr("* Running as user : %1").arg(user_name));
|
|
str.append(QObject::tr("* Firewall name : %1")
|
|
.arg(QString::fromUtf8(cnf.fwobj->getName().c_str())));
|
|
str.append(QObject::tr("* Installer uses user name : %1").arg(cnf.user));
|
|
|
|
// print destination machine address or name correctly, taking into
|
|
// account putty session if any
|
|
if (!cnf.putty_session.isEmpty())
|
|
str.append(QObject::tr("* Using putty session: %1").arg(cnf.putty_session));
|
|
else
|
|
str.append(QObject::tr("* Management address : %1").arg(cnf.maddr));
|
|
|
|
str.append(QObject::tr("* Platform : %1")
|
|
.arg(cnf.fwobj->getStr("platform").c_str()));
|
|
str.append(QObject::tr("* Host OS : %1")
|
|
.arg(cnf.fwobj->getStr("host_OS").c_str()));
|
|
str.append(QObject::tr("* Loading configuration from file %1")
|
|
.arg(cnf.fwbfile));
|
|
|
|
if (cnf.save_diff)
|
|
str.append(QObject::tr("* Configuration diff will be saved in file %1").
|
|
arg(cnf.diff_file));
|
|
|
|
if (cnf.dry_run)
|
|
str.append(QObject::tr("* Commands will not be executed on the firewall"));
|
|
|
|
if (fwbdebug)
|
|
{
|
|
str.append(QObject::tr("--------------------------------"));
|
|
str.append(QObject::tr("* Variables:"));
|
|
str.append(QObject::tr("* fwdir= %1") .arg(cnf.fwdir));
|
|
str.append(QObject::tr("* fwscript= %1") .arg(cnf.fwscript));
|
|
str.append(QObject::tr("* remote_script= %1") .arg(cnf.remote_script));
|
|
}
|
|
|
|
str.append("");
|
|
|
|
QTextCursor cursor = m_dialog->procLogDisplay->textCursor();
|
|
cursor.insertBlock();
|
|
cursor.insertText(str.join("\n"), highlight_format);
|
|
}
|
|
|
|
void instDialog::fillCompileSelectList()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::fillCompileSelectList");
|
|
|
|
Firewall *fw;
|
|
Cluster *cl;
|
|
QDateTime dt;
|
|
|
|
creatingTable = true;
|
|
m_dialog->selectTable->clear();
|
|
|
|
list<Firewall*> working_list_of_firewalls = firewalls;
|
|
|
|
for (list<Cluster *>::iterator i=clusters.begin(); i!=clusters.end(); ++i)
|
|
{
|
|
cl = *i;
|
|
|
|
QTreeWidgetItem* cluster_item = createTreeItem(NULL, cl);
|
|
m_dialog->selectTable->addTopLevelItem(cluster_item);
|
|
|
|
list<Firewall*> members;
|
|
cl->getMembersList(members);
|
|
|
|
for (list<Firewall*>::iterator member=members.begin();
|
|
member!=members.end(); ++member)
|
|
{
|
|
createTreeItem(cluster_item, *member);
|
|
working_list_of_firewalls.remove(*member);
|
|
}
|
|
cluster_item->setExpanded(true);
|
|
}
|
|
|
|
for (list<Firewall *>::iterator i=working_list_of_firewalls.begin();
|
|
i!=working_list_of_firewalls.end(); ++i)
|
|
{
|
|
fw = *i;
|
|
QTreeWidgetItem* fw_item = createTreeItem(NULL, fw);
|
|
m_dialog->selectTable->addTopLevelItem(fw_item);
|
|
}
|
|
|
|
QTreeWidgetItemIterator it(m_dialog->selectTable);
|
|
while (*it)
|
|
{
|
|
setFlags(*it);
|
|
++it;
|
|
}
|
|
|
|
|
|
/* ticket #1305
|
|
* check if any of the firewall objects are members of clusters but
|
|
* the clusters are not requested for compile
|
|
*/
|
|
|
|
QString warn1(
|
|
tr("<b>You are trying to compile policy for a firewall object that is "
|
|
"a member of a cluster, however you requested compilation of only "
|
|
"this member firewall and not the cluster it belongs to. Assuming "
|
|
"firewall is standalone and not cluster member. Rules and parts of "
|
|
"the script specific for the cluster configuration will not be "
|
|
"generated.</b>"));
|
|
|
|
QStringList warn2;
|
|
|
|
list<FWObject*> all_libs = project->db()->getByType(Library::TYPENAME);
|
|
foreach(FWObject *lib, all_libs)
|
|
{
|
|
if (lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) continue;
|
|
list<FWObject*> all_clusters = lib->getByTypeDeep(Cluster::TYPENAME);
|
|
foreach(FWObject *_cl, all_clusters)
|
|
{
|
|
if (std::find(clusters.begin(), clusters.end(), _cl) == clusters.end())
|
|
{
|
|
Cluster *cluster = Cluster::cast(_cl);
|
|
assert(cluster);
|
|
foreach(FWObject *fw, firewalls)
|
|
{
|
|
if (cluster->hasMember(Firewall::cast(fw)))
|
|
{
|
|
warn2 <<
|
|
QString(tr("Firewall '%1' is member of cluster '%2'")
|
|
.arg(QString::fromUtf8(fw->getName().c_str()))
|
|
.arg(QString::fromUtf8(cluster->getPath().c_str())));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!warn2.empty())
|
|
{
|
|
m_dialog->warning_message_1->setText(warn1);
|
|
m_dialog->warning_message_2->setText(warn2.join("\n"));
|
|
m_dialog->warning_space->show();
|
|
}
|
|
|
|
creatingTable = false;
|
|
|
|
for (int i=0; i<m_dialog->selectTable->columnCount(); i++)
|
|
m_dialog->selectTable->resizeColumnToContents(i);
|
|
|
|
setNextEnabled(0, tableHasCheckedItems());
|
|
//m_dialog->selectTable->resizeRowsToContents();
|
|
}
|
|
|
|
void instDialog::displayCommand(const QStringList &args)
|
|
{
|
|
QStringList a1 = args;
|
|
|
|
for (QStringList::iterator i=a1.begin(); i!=a1.end(); i++)
|
|
{
|
|
if ( (*i)=="-pw" )
|
|
{
|
|
i++;
|
|
*i = "XXXXXX";
|
|
break;
|
|
}
|
|
}
|
|
QString s=a1.join(" ");
|
|
addToLog( tr("Running command '%1'\n").arg(s) );
|
|
}
|
|
|
|
void instDialog::updateProgressBar(int n, bool setsize)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("instDialog::updateProgressBar n=%d setsize=%d",n,setsize);
|
|
|
|
if (setsize) currentProgressBar->setMaximum(n);
|
|
else
|
|
currentProgressBar->setValue(currentProgressBar->maximum()-n);
|
|
}
|
|
|
|
void instDialog::finishClicked()
|
|
{
|
|
finished = true;
|
|
accept();
|
|
}
|
|
|
|
/* user clicked 'Cancel' */
|
|
void instDialog::cancelClicked()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::cancelClicked()");
|
|
finished = true;
|
|
|
|
if (proc.state() == QProcess::Running)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::cancelClicked killing background process";
|
|
rejectDialogFlag = true;
|
|
proc.kill();
|
|
}
|
|
|
|
if (installer != NULL)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::cancelClicked killing installer";
|
|
installer->terminate();
|
|
delete installer;
|
|
installer = NULL;
|
|
}
|
|
|
|
QDialog::reject();
|
|
}
|
|
|
|
|
|
void instDialog::showEvent( QShowEvent *ev)
|
|
{
|
|
st->restoreGeometry(this, QRect(200,100,780,500) );
|
|
QDialog::showEvent(ev);
|
|
}
|
|
|
|
void instDialog::hideEvent( QHideEvent *ev)
|
|
{
|
|
st->saveGeometry(this);
|
|
QDialog::hideEvent(ev);
|
|
}
|
|
|
|
void instDialog::saveLog()
|
|
{
|
|
QString dir;
|
|
//if (m_dialog->procLogDisplay==NULL) return;
|
|
dir=st->getWDir();
|
|
if (dir.isEmpty()) dir=st->getOpenFileDir();
|
|
if (dir.isEmpty()) dir="~";
|
|
|
|
/*
|
|
* We use QTextEdit::append to add lines to the log buffer, each
|
|
append creates a new paragraph so QTextEdit::text returns only
|
|
contents of the last paragraph. Need to reassemble the whole text
|
|
adding text from each paragraph separately.
|
|
*/
|
|
QString logText;
|
|
logText = m_dialog->procLogDisplay->toPlainText();
|
|
|
|
QString s = QFileDialog::getSaveFileName(
|
|
this,
|
|
"Choose a file",
|
|
dir,
|
|
"Text file (*.txt)");
|
|
|
|
if (fwbdebug)
|
|
qDebug( "Saving log to file %s", s.toAscii().constData() );
|
|
|
|
if (!s.isEmpty())
|
|
{
|
|
if (!s.endsWith(".txt"))
|
|
{
|
|
s+=".txt";
|
|
}
|
|
|
|
QFile f(s);
|
|
if (f.open( QIODevice::WriteOnly ))
|
|
{
|
|
QTextStream str( &f );
|
|
str << logText;
|
|
f.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Adds one line of text to the log
|
|
*
|
|
*/
|
|
void instDialog::addToLog(const QString &buf)
|
|
{
|
|
if (buf.isEmpty()) return;
|
|
|
|
foreach(QString line, buf.trimmed().split("\n"))
|
|
{
|
|
QTextCharFormat format = normal_format;
|
|
|
|
list<QRegExp>::const_iterator it;
|
|
for (it=error_re.begin(); it!=error_re.end(); ++it)
|
|
{
|
|
if ((*it).indexIn(line) != -1)
|
|
{
|
|
format = error_format;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (it=warning_re.begin(); it!=warning_re.end(); ++it)
|
|
{
|
|
if ((*it).indexIn(line) != -1)
|
|
{
|
|
format = warning_format;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* See sourceforge bug https://sourceforge.net/tracker/?func=detail&aid=2847263&group_id=5314&atid=1070394
|
|
*
|
|
* QTextEditor::insertHtml() becomes incrementally slow as the
|
|
* amount of text already in the QTextEditor
|
|
* increases. Compiling ~10 firewalls with few dozen rules
|
|
* each slows the output to a crawl on Windows. Keeping each
|
|
* line in a separate block makes it much faster.
|
|
*/
|
|
|
|
QString txt = line;
|
|
while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r")))
|
|
txt.chop(1);
|
|
|
|
if (format == error_format || format == warning_format )
|
|
format.setAnchorHref(txt);
|
|
|
|
QTextCursor cursor = m_dialog->procLogDisplay->textCursor();
|
|
|
|
cursor.insertBlock();
|
|
|
|
cursor.insertText(txt, format);
|
|
}
|
|
|
|
//m_dialog->procLogDisplayList->addItem(txt);
|
|
|
|
m_dialog->procLogDisplay->ensureCursorVisible();
|
|
|
|
//qApp->processEvents();
|
|
}
|
|
|
|
void instDialog::interpretLogLine(const QString &line)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug("instDialog::interpretLogLine %s", line.toAscii().constData() );
|
|
|
|
QStringList words = line.trimmed().split(" ");
|
|
|
|
if (fwbdebug)
|
|
{
|
|
for (int i=0; i<words.size(); ++i)
|
|
qDebug("instDialog::interpretLogLine words[%d]='%s'",
|
|
i, words[i].toAscii().constData());
|
|
}
|
|
|
|
if (words.first().indexOf("rule")>=0)
|
|
{
|
|
bool ok;
|
|
processedRules = words[1].toInt(&ok);
|
|
if (ok)
|
|
currentProgressBar->setValue(processedRules);
|
|
|
|
if (fwbdebug)
|
|
qDebug("instDialog::interpretLogLine set progress bar current=%d",
|
|
processedRules);
|
|
} else
|
|
{
|
|
if (words.first().indexOf("processing")>=0)
|
|
{
|
|
currentProgressBar->reset();
|
|
bool ok;
|
|
int totalRules = words[1].toInt(&ok);
|
|
if (ok)
|
|
currentProgressBar->setMaximum(totalRules);
|
|
processedRules = 0;
|
|
|
|
if (fwbdebug)
|
|
qDebug("instDialog::interpretLogLine set progress bar max=%d",
|
|
totalRules);
|
|
} else
|
|
{
|
|
if (words.first().indexOf("Compiling")>=0)
|
|
{
|
|
//currentLabel->setText(line.trimmed());
|
|
currentProgressBar->reset();
|
|
} else
|
|
{
|
|
if (line.indexOf("Compiled successfully")>=0)
|
|
{
|
|
//currentLabel->setText(line.trimmed());
|
|
currentProgressBar->setValue(currentProgressBar->maximum());
|
|
if (fwbdebug)
|
|
qDebug("instDialog::interpretLogLine set progress "
|
|
"bar to max");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,1);
|
|
}
|
|
|
|
void instDialog::readFromStdout()
|
|
{
|
|
char buf[2048];
|
|
int read_status = 0;
|
|
while ((read_status = proc.readLine(buf, sizeof(buf)))>0)
|
|
{
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("instDialog::readFromStdout: read_status=%d buf=%s",
|
|
read_status, buf);
|
|
}
|
|
addToLog(buf);
|
|
interpretLogLine(buf);
|
|
}
|
|
}
|
|
|
|
void instDialog::selectAllFirewalls()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::selectAllFirewalls");
|
|
setSelectStateAll(INSTALL_CHECKBOX_COLUMN, Qt::Checked);
|
|
setSelectStateAll(COMPILE_CHECKBOX_COLUMN, Qt::Checked);
|
|
tableItemChanged(NULL, 0);
|
|
}
|
|
|
|
void instDialog::deselectAllFirewalls()
|
|
{
|
|
setSelectStateAll(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked);
|
|
setSelectStateAll(COMPILE_CHECKBOX_COLUMN, Qt::Unchecked);
|
|
tableItemChanged(NULL, 0);
|
|
}
|
|
|
|
void instDialog::setSelectStateAll(int column, Qt::CheckState select)
|
|
{
|
|
QTreeWidgetItemIterator it(m_dialog->selectTable);
|
|
while (*it)
|
|
{
|
|
int obj_id = (*it)->data(0, Qt::UserRole).toInt();
|
|
FWObject *o = project->db()->findInIndex(obj_id);
|
|
bool cluster_member = (*it)->data(1, Qt::UserRole).toBool();
|
|
int num_members = (*it)->data(2, Qt::UserRole).toInt();
|
|
|
|
Qt::ItemFlags flags = (*it)->flags();
|
|
if ((flags & Qt::ItemIsUserCheckable) != 0)
|
|
{
|
|
// firewalls only get checkboxes for install,
|
|
if (column == INSTALL_CHECKBOX_COLUMN && Firewall::isA(o))
|
|
(*it)->setCheckState(column, select);
|
|
|
|
// Cluster gets checkbox for compile.
|
|
// Cluster should never get a checkbox if it has no members.
|
|
// Firewall that is not a cluster member gets compile checkbox
|
|
if ((column == COMPILE_CHECKBOX_COLUMN && Cluster::isA(o) && num_members) ||
|
|
(Firewall::isA(o) && !cluster_member))
|
|
(*it)->setCheckState(column, select);
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void instDialog::fillCompileOpList()
|
|
{
|
|
compile_fw_list.clear();
|
|
QTreeWidgetItemIterator it(m_dialog->selectTable);
|
|
while (*it)
|
|
{
|
|
if ((*it)->checkState(COMPILE_CHECKBOX_COLUMN))
|
|
{
|
|
int obj_id = (*it)->data(0, Qt::UserRole).toInt();
|
|
FWObject *o = project->db()->findInIndex(obj_id);
|
|
compile_fw_list.push_back(Firewall::cast(o));
|
|
}
|
|
++it;
|
|
}
|
|
compile_list_initial_size = compile_fw_list.size();
|
|
}
|
|
|
|
void instDialog::fillCompileUIList()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::fillCompileUIList");
|
|
|
|
m_dialog->fwWorkList->clear();
|
|
opListMapping.clear();
|
|
|
|
Firewall * f;
|
|
InstallFirewallViewItem * item;
|
|
list<Firewall*>::iterator i;
|
|
for(i=compile_fw_list.begin(); i!=compile_fw_list.end(); ++i)
|
|
{
|
|
f = (*i);
|
|
item = new InstallFirewallViewItem(
|
|
NULL,//m_dialog->fwWorkList,
|
|
QString::fromUtf8(f->getName().c_str()),
|
|
false);
|
|
|
|
item->setData(0, Qt::UserRole, QVariant(f->getId()));
|
|
m_dialog->fwWorkList->insertTopLevelItem(0, item);
|
|
|
|
opListMapping[f->getId()] = item;
|
|
}
|
|
|
|
m_dialog->fwWorkList->resizeColumnToContents(0);
|
|
m_dialog->fwWorkList->sortByColumn(0, Qt::AscendingOrder);
|
|
}
|
|
|
|
void instDialog::fillInstallOpList()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::fillInstallOpList");
|
|
install_fw_list.clear();
|
|
QTreeWidgetItemIterator it(m_dialog->selectTable);
|
|
while (*it)
|
|
{
|
|
if ((*it)->checkState(INSTALL_CHECKBOX_COLUMN))
|
|
{
|
|
int obj_id = (*it)->data(0, Qt::UserRole).toInt();
|
|
FWObject *o = project->db()->findInIndex(obj_id);
|
|
install_fw_list.push_back(Firewall::cast(o));
|
|
if (fwbdebug)
|
|
qDebug("fillInstallOpList: Install requested for %s", o->getName().c_str());
|
|
}
|
|
++it;
|
|
}
|
|
install_list_initial_size = install_fw_list.size();
|
|
}
|
|
|
|
void instDialog::fillInstallUIList()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::fillInstallUIList");
|
|
|
|
m_dialog->fwWorkList->clear();
|
|
opListMapping.clear();
|
|
|
|
Firewall * f;
|
|
InstallFirewallViewItem * item;
|
|
list<Firewall*>::iterator i;
|
|
for(i=install_fw_list.begin(); i!=install_fw_list.end(); ++i)
|
|
{
|
|
f = (*i);
|
|
item = new InstallFirewallViewItem(
|
|
NULL,
|
|
QString::fromUtf8(f->getName().c_str()),
|
|
false);
|
|
|
|
m_dialog->fwWorkList->insertTopLevelItem(0, item);
|
|
opListMapping[f->getId()] = item;
|
|
}
|
|
m_dialog->fwWorkList->resizeColumnToContents(0);
|
|
m_dialog->fwWorkList->sortByColumn(0, Qt::AscendingOrder);
|
|
}
|
|
|
|
void instDialog::findFirewallInCompileLog(QTreeWidgetItem* item)
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::findFirewallInCompileLog");
|
|
|
|
m_dialog->detailMCframe->show();
|
|
qApp->processEvents();
|
|
QString fw_name = item->text(0);
|
|
|
|
m_dialog->procLogDisplay->moveCursor( QTextCursor::End );
|
|
m_dialog->procLogDisplay->find(currentSearchString +
|
|
fw_name,
|
|
QTextDocument::FindWholeWords |
|
|
QTextDocument::FindCaseSensitively |
|
|
QTextDocument::FindBackward);
|
|
}
|
|
|
|
void instDialog::tableItemChanged(QTreeWidgetItem*, int)
|
|
{
|
|
if (!creatingTable)
|
|
setNextEnabled(0, tableHasCheckedItems());
|
|
}
|
|
|
|
bool instDialog::tableHasCheckedItems()
|
|
{
|
|
QTreeWidgetItemIterator it(m_dialog->selectTable);
|
|
while (*it)
|
|
{
|
|
if ((*it)->checkState(COMPILE_CHECKBOX_COLUMN) ||
|
|
(*it)->checkState(INSTALL_CHECKBOX_COLUMN))
|
|
return true;
|
|
++it;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* getInstOptions() fills attributes of the cnf object
|
|
*/
|
|
bool instDialog::getInstOptions(Firewall *fw, bool cancelAllVisible)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::getInstOptions() begin"
|
|
<< "cnf.user=" << cnf.user
|
|
<< "cnf.maddr=" << cnf.maddr
|
|
<< "fw=" << fw;
|
|
|
|
cnf.fwobj = fw;
|
|
|
|
readInstallerOptionsFromSettings();
|
|
readInstallerOptionsFromFirewallObject(fw);
|
|
|
|
if (m_dialog->batchInstall->isChecked() && batch_inst_opt_dlg)
|
|
{
|
|
// in batch install mode we use the same dialog to fill cnf
|
|
// without showing it to the user again
|
|
readInstallerOptionsFromDialog(fw, batch_inst_opt_dlg);
|
|
} else
|
|
{
|
|
// In non-batch mode installer options from the dialog
|
|
// overwrite options set in the fw object itself.
|
|
instOptionsDialog *inst_opt_dlg = new instOptionsDialog(
|
|
this, &cnf, cancelAllVisible);
|
|
|
|
int resultCode = inst_opt_dlg->exec();
|
|
// 0 - rejected
|
|
// 1 - accepted
|
|
// -1 - cancell all clicked
|
|
if (resultCode == -1)
|
|
{
|
|
canceledAll = true;
|
|
delete inst_opt_dlg;
|
|
return false;
|
|
}
|
|
if (resultCode == QDialog::Rejected)
|
|
{
|
|
delete inst_opt_dlg;
|
|
return false;
|
|
}
|
|
readInstallerOptionsFromDialog(fw, inst_opt_dlg);
|
|
inst_opt_dlg->close();
|
|
inst_opt_dlg->deleteLater();
|
|
}
|
|
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::getInstOptions() end"
|
|
<< "cnf.user=" << cnf.user
|
|
<< "cnf.maddr=" << cnf.maddr;
|
|
|
|
return verifyManagementAddress();
|
|
}
|
|
|
|
/*
|
|
* getBatchInstOptions() fills attributes of the cnf object for batch install
|
|
*/
|
|
bool instDialog::getBatchInstOptions(Firewall *first_fw)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::getBatchInstOptions() begin"
|
|
<< "cnf.user=" << cnf.user
|
|
<< "cnf.maddr=" << cnf.maddr
|
|
<< "first_fw=" << first_fw;
|
|
|
|
cnf.fwobj = first_fw; // NULL;
|
|
|
|
readInstallerOptionsFromSettings();
|
|
readInstallerOptionsFromFirewallObject(first_fw);
|
|
|
|
if (batch_inst_opt_dlg != NULL) delete batch_inst_opt_dlg;
|
|
|
|
batch_inst_opt_dlg = new instBatchOptionsDialog(this, &cnf);
|
|
|
|
if (batch_inst_opt_dlg->exec()==QDialog::Rejected)
|
|
{
|
|
stopProcessFlag = true;
|
|
this->m_dialog->finishButton->setEnabled(true);
|
|
this->m_dialog->finishButton->setDefault(true);
|
|
foreach(Firewall *fw, this->install_fw_list)
|
|
this->opCancelled(fw);
|
|
return false;
|
|
}
|
|
// clear aternative address in the dialog
|
|
batch_inst_opt_dlg->m_dialog->altAddress->setText("");
|
|
readInstallerOptionsFromDialog(NULL, batch_inst_opt_dlg);
|
|
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::getBatchInstOptions() end"
|
|
<< "cnf.user=" << cnf.user
|
|
<< "cnf.maddr=" << cnf.maddr;
|
|
|
|
return verifyManagementAddress();
|
|
}
|
|
|
|
void instDialog::readInstallerOptionsFromSettings()
|
|
{
|
|
if (fwbdebug) qDebug("instDialog::readInstallerOptionsFromSettings");
|
|
|
|
fwb_prompt="--**--**--";
|
|
|
|
cnf.batchInstall = m_dialog->batchInstall->isChecked();
|
|
|
|
cnf.save_diff = st->value(SETTINGS_PATH_PREFIX"/Installer/savediff").toBool();
|
|
cnf.saveStandby = st->value(SETTINGS_PATH_PREFIX"/Installer/saveStandby").toBool();
|
|
cnf.dry_run = st->value(SETTINGS_PATH_PREFIX"/Installer/dryrun").toBool();
|
|
cnf.quiet = st->value(SETTINGS_PATH_PREFIX"/Installer/quiet").toBool();
|
|
cnf.verbose = st->value(SETTINGS_PATH_PREFIX"/Installer/verbose" ).toBool();
|
|
cnf.stripComments = st->value(SETTINGS_PATH_PREFIX"/Installer/stripComments").toBool();
|
|
cnf.compressScript = st->value(SETTINGS_PATH_PREFIX"/Installer/compressScript").toBool();
|
|
cnf.copyFWB = st->value(SETTINGS_PATH_PREFIX"/Installer/copyFWB").toBool();
|
|
}
|
|
|
|
void instDialog::readInstallerOptionsFromFirewallObject(Firewall *fw)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::readInstallerOptionsFromFirewallObject"
|
|
<< "fw=" << fw
|
|
<< QString( (fw) ? QString::fromUtf8(fw->getName().c_str()) : "");
|
|
|
|
FWOptions *fwopt = NULL;
|
|
if (fw)
|
|
{
|
|
fwopt = fw->getOptionsObject();
|
|
|
|
string platform = cnf.fwobj->getStr("platform");
|
|
string host_OS = cnf.fwobj->getStr("host_OS");
|
|
|
|
cnf.user = fwopt->getStr("admUser").c_str();
|
|
|
|
QString standard_management_addr;
|
|
// Note that Host::getManagementAddress() scans interfaces and
|
|
// finds one marked as "management" and takes its address.
|
|
// It does not use Management child object.
|
|
const InetAddr *mgmt_addr = cnf.fwobj->getManagementAddress();
|
|
if (mgmt_addr)
|
|
standard_management_addr = mgmt_addr->toString().c_str();
|
|
else
|
|
standard_management_addr = "";
|
|
|
|
QString aaddr = fwopt->getStr("altAddress").c_str();
|
|
|
|
if (fwbdebug)
|
|
qDebug() << " standard_management_addr="
|
|
<< standard_management_addr
|
|
<< "aaddr=" << aaddr;
|
|
|
|
if (!aaddr.isEmpty()) cnf.maddr = aaddr;
|
|
else cnf.maddr = standard_management_addr;
|
|
|
|
cnf.putty_session = "";
|
|
|
|
#ifdef _WIN32
|
|
|
|
/*
|
|
* See #1724. There is a problem with pscp.exe and putty
|
|
* sessions. Plink.exe accepts session name in place of the host name
|
|
* on the command line, but pscp.exe does not. We ask user to enter
|
|
* session name in the "alternative name or address to use to
|
|
* communicate with the firewall" input field in the "Installer" tab
|
|
* of the firewall settings dialog and then use it in place of the
|
|
* host name in the command line for pscp.exe and plink.exe. This
|
|
* works with plink.exe but breaks pscp.exe which interprets it as a
|
|
* host name and fails with an error ""ssh_init: Host does not exist".
|
|
*
|
|
* Will try to determine if what user entered in the "alternative host
|
|
* or address field" is a session name and use different command line
|
|
* for pscp.exe
|
|
*
|
|
*
|
|
* HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\<session_name>
|
|
*/
|
|
|
|
QSettings putty_reg(QSettings::UserScope, "SimonTatham", "PuTTY\\Sessions");
|
|
QStringList sessions = putty_reg.childGroups();
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug() << putty_reg.fileName();
|
|
qDebug() << "found " << sessions.size() << " putty sessions";
|
|
foreach(QString key, sessions)
|
|
{
|
|
qDebug() << "putty session " << key;
|
|
}
|
|
}
|
|
|
|
if (sessions.contains(aaddr))
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "Found matching putty session" << aaddr;
|
|
cnf.maddr = standard_management_addr;
|
|
cnf.putty_session = aaddr;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
* if user requested test run, store firewall script in a temp
|
|
* file. Always store it in a temp file on linksys
|
|
*/
|
|
QString s;
|
|
|
|
/* user_can_change_install_dir */
|
|
bool uccid = Resources::getTargetOptionBool(
|
|
host_OS, "user_can_change_install_dir");
|
|
|
|
if (uccid) s = fwopt->getStr("firewall_dir").c_str();
|
|
|
|
if (s.isEmpty()) s = Resources::getTargetOptionStr(
|
|
host_OS, "activation/fwdir").c_str();
|
|
|
|
cnf.fwdir = s;
|
|
|
|
/*
|
|
* Generated files should be saved in the same directory where
|
|
* the .fwb file is located, except if user specified full path
|
|
* in the advaced settings dialog.
|
|
*/
|
|
cnf.script = FirewallInstaller::getGeneratedFileFullPath(fw);
|
|
// cnf.script = FirewallInstaller::getGeneratedFileName(fw);
|
|
cnf.remote_script = ""; // filled in FirewallInstaller::readManifest()
|
|
cnf.fwbfile = project->db()->getFileName().c_str();
|
|
cnf.wdir = getFileDir( project->getRCS()->getFileName() );
|
|
cnf.diff_file = QString(cnf.fwobj->getName().c_str())+".diff";
|
|
cnf.diff_pgm = Resources::platform_res[platform]->
|
|
getResourceStr("/FWBuilderResources/Target/diff").c_str();
|
|
cnf.diff_pgm = getPathToBinary(
|
|
cnf.diff_pgm.toAscii().constData()).c_str();
|
|
#ifdef _WIN32
|
|
cnf.diff_pgm = cnf.diff_pgm + ".exe";
|
|
#endif
|
|
cnf.sshArgs = fwopt->getStr("sshArgs").c_str();
|
|
cnf.scpArgs = fwopt->getStr("scpArgs").c_str();
|
|
cnf.useSCPForRouter = fwopt->getBool("use_scp");
|
|
|
|
cnf.activationCmd = fwopt->getStr("activationCmd").c_str();
|
|
|
|
if (fwbdebug)
|
|
{
|
|
qDebug("platform: %s", platform.c_str());
|
|
qDebug("host_OS: %s", host_OS.c_str());
|
|
qDebug("user_can_change_install_dir=%d", uccid);
|
|
qDebug("firewall_dir='%s'", fwopt->getStr("firewall_dir").c_str());
|
|
qDebug("management address: %s", cnf.maddr.toAscii().constData());
|
|
qDebug("cnf.fwdir='%s'", cnf.fwdir.toAscii().constData());
|
|
qDebug("activationCmd='%s'", cnf.activationCmd.toAscii().constData());
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void instDialog::readInstallerOptionsFromDialog(Firewall *fw,
|
|
instOptionsDialog *dlg)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::readInstallerOptionsFromDialog"
|
|
<< "fw=" << fw;
|
|
|
|
QString adm_user;
|
|
|
|
FWOptions *fwopt = NULL;
|
|
if (fw)
|
|
{
|
|
fwopt = cnf.fwobj->getOptionsObject();
|
|
adm_user = fwopt->getStr("admUser").c_str();
|
|
}
|
|
|
|
cnf.dry_run = dlg->m_dialog->test->isChecked();
|
|
cnf.backup_file = dlg->m_dialog->backupConfigFile->text();
|
|
cnf.backup = !cnf.backup_file.isEmpty();
|
|
cnf.save_diff = dlg->m_dialog->saveDiff->isChecked();
|
|
cnf.saveStandby = dlg->m_dialog->saveStandby->isChecked();
|
|
|
|
/* Alternative address:
|
|
- first, check dialog. User could have overriden it using dialog
|
|
- then check firewall options, user could have set it in the "Install"
|
|
tab of firewall settings dialog
|
|
- last, if all overrides are empty, take it from the management interface
|
|
*/
|
|
|
|
QString aaddr = dlg->m_dialog->altAddress->text();
|
|
if (!aaddr.isEmpty())
|
|
{
|
|
/* alternative address can also be putty session name. In any case,
|
|
* leave it up to ssh to resolve it and signal an error if it can't be
|
|
* resolved ( Putty session name does not have to be in DNS at all ).
|
|
*/
|
|
cnf.maddr = aaddr;
|
|
if (fwbdebug)
|
|
qDebug() << "alternative addr:" << aaddr;
|
|
}
|
|
|
|
// user name set in the dialog overrides that set in the fw object
|
|
// But the dialog user name input field can be left blank, in which
|
|
// case we use the one configured in the object
|
|
if (!adm_user.isEmpty()) cnf.user = adm_user;
|
|
if (!dlg->m_dialog->uname->text().isEmpty())
|
|
cnf.user = dlg->m_dialog->uname->text();
|
|
|
|
cnf.pwd = dlg->m_dialog->pwd->text();
|
|
cnf.epwd = dlg->m_dialog->epwd->text();
|
|
cnf.quiet = dlg->m_dialog->quiet->isChecked();
|
|
cnf.verbose = dlg->m_dialog->verbose->isChecked();
|
|
cnf.stripComments = dlg->m_dialog->stripComments->isChecked();
|
|
cnf.compressScript= dlg->m_dialog->compressScript->isChecked();
|
|
cnf.copyFWB = dlg->m_dialog->copyFWB->isChecked();
|
|
|
|
dlg->savePassword();
|
|
storeInstallerOptions();
|
|
}
|
|
|
|
bool instDialog::verifyManagementAddress()
|
|
{
|
|
/* check for a common error when none or multiple interfaces are marked as
|
|
* 'management'
|
|
*/
|
|
if (cnf.maddr.isEmpty() && cnf.putty_session.isEmpty() && cnf.fwobj)
|
|
{
|
|
int nmi = 0;
|
|
list<FWObject*> ll = cnf.fwobj->getByTypeDeep(Interface::TYPENAME);
|
|
for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++)
|
|
{
|
|
Interface *intf = Interface::cast( *i );
|
|
if (intf->isManagement()) nmi++;
|
|
}
|
|
|
|
if (nmi>1)
|
|
{
|
|
QString err = QObject::tr("Only one interface of the firewall '%1' "
|
|
"must be marked as management interface.\n")
|
|
.arg(QString::fromUtf8(cnf.fwobj->getName().c_str()));
|
|
|
|
QMessageBox::critical(this, "Firewall Builder", err,
|
|
tr("&Continue") );
|
|
addToLog(err);
|
|
return false;
|
|
}
|
|
|
|
if (nmi==0)
|
|
{
|
|
QString err = QObject::tr(
|
|
"One of the interfaces of the firewall '%1' "
|
|
"must be marked as management interface. "
|
|
"To set the management interface, double click "
|
|
"on the interface of the firewall that you will "
|
|
"connect to and check the box called Management "
|
|
"interface in the Editor panel")
|
|
.arg(QString::fromUtf8(cnf.fwobj->getName().c_str()));
|
|
|
|
QMessageBox::critical(this, "Firewall Builder", err,
|
|
tr("&Continue") );
|
|
addToLog(err);
|
|
return false;
|
|
}
|
|
|
|
if (cnf.maddr == "" ||
|
|
cnf.maddr == QString(InetAddr::getAny().toString().c_str()))
|
|
{
|
|
QString err = QObject::tr(
|
|
"Management interface does not have IP address, "
|
|
"can not communicate with the firewall.\n");
|
|
|
|
QMessageBox::critical(this, "Firewall Builder", err,
|
|
tr("&Continue") );
|
|
addToLog(err);
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void instDialog::logItemClicked(QUrl data)
|
|
{
|
|
QStringList parts = data.toString().split(':');
|
|
if (parts[0] == "Error") return;
|
|
if (parts.size()<3)
|
|
{
|
|
if(fwbdebug)
|
|
cout << "Wrong error message clicked" << endl;
|
|
return;
|
|
}
|
|
emit activateRule(project, parts[0], parts[1], parts[2].toInt());
|
|
}
|
|
|
|
void instDialog::closeEvent(QCloseEvent *)
|
|
{
|
|
if (fwbdebug) qDebug() << "instDialog::closeEvent";
|
|
if (proc.state() == QProcess::Running)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::closeEvent killing process";
|
|
proc.kill();
|
|
}
|
|
if (installer != NULL)
|
|
{
|
|
if (fwbdebug)
|
|
qDebug() << "instDialog::closeEvent killing installer";
|
|
installer->terminate();
|
|
delete installer;
|
|
installer = NULL;
|
|
}
|
|
}
|