/* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fwbuilder/Resources.h" #include "fwbuilder/FWObjectDatabase.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 // for access(2) and getdomainname #endif #include #include 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() && reqFirewalls.empty() && !fw->getInactive()) || (!onlySelected && !reqFirewalls.empty() && reqFirewalls.find(fw)!=reqFirewalls.end() || (onlySelected && fw->needsCompile() && !fw->getInactive()) ); } bool instDialog::checkIfNeedToInstall(Firewall *fw) { return ((fw->needsInstall() && reqFirewalls.empty() && !fw->getInactive()) || (!reqFirewalls.empty() && reqFirewalls.find(fw)!=reqFirewalls.end())); } QTreeWidgetItem* instDialog::createTreeItem(QTreeWidgetItem* parent, Firewall *fw) { QTreeWidgetItem* item; QStringList sl; sl.push_back(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 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; // 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); 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) && ! compile_only) { bool checked = false; 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 members; Cluster::cast(fw)->getMembersList(members); num_members = members.size(); if (num_members) { bool checked = checkIfNeedToCompile(fw); // if any of the member firewalls are in reqFirewalls, re-check // if we need to compile the cluster. checkIfNeedToCompile() // uses different condition if reqFirewalls is not empty. for (list::iterator it=members.begin(); it!=members.end(); ++it) { if (reqFirewalls.find(*it)!=reqFirewalls.end() && fw->needsCompile() && !fw->getInactive()) checked = true; } 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) { opListMapping[(fw)->getId()]->setText(1,tr("Success")); setSuccessState(opListMapping[(fw)->getId()]); currentLabel->setText(""); } void instDialog::opError(Firewall *fw) { opListMapping[(fw)->getId()]->setText(1, tr("Error")); setErrorState(opListMapping[(fw)->getId()]); currentLabel->setText(""); } void instDialog::opCancelled(Firewall *fw) { opListMapping[(fw)->getId()]->setText(1, tr("Cancelled")); setErrorState(opListMapping[(fw)->getId()]); currentLabel->setText(""); } void instDialog::nextClicked() { if (nextRelevant( currentPage() ) > -1) showPage(nextRelevant( currentPage() )); } void instDialog::backClicked() { if (previousRelevant( currentPage() ) > -1) showPage(previousRelevant( currentPage() )); } 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); st->setValue(SETTINGS_PATH_PREFIX"/Installer/testRun", cnf.testRun); st->setValue(SETTINGS_PATH_PREFIX"/Installer/rollback", cnf.rollback); st->setValue(SETTINGS_PATH_PREFIX"/Installer/rollbackTime", cnf.rollbackTime); st->setValue(SETTINGS_PATH_PREFIX"/Installer/canceRollbackIfSuccess", cnf.cancelRollbackIfSuccess); } 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)); 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")); str.append(""); QTextCursor cursor = currentLog->textCursor(); cursor.insertBlock(); cursor.insertText(str.join("\n"), highlight_format); } void instDialog::fillCompileSelectList() { if (fwbdebug) qDebug("instDialog::fillCompileSelectList"); Firewall *fw; Cluster *cl; QDateTime dt; if (fwbdebug && reqFirewalls.empty()) qDebug("instDialog::fillCompileSelectList reqFirewalls is empty"); creatingTable = true; list working_list_of_firewalls = firewalls; for (list::iterator i=clusters.begin(); i!=clusters.end(); ++i) { cl = *i; QTreeWidgetItem* cluster_item = createTreeItem(NULL, cl); m_dialog->selectTable->addTopLevelItem(cluster_item); list members; cl->getMembersList(members); for (list::iterator member=members.begin(); member!=members.end(); ++member) { QTreeWidgetItem *itm = createTreeItem(cluster_item, *member); working_list_of_firewalls.remove(*member); } cluster_item->setExpanded(true); } for (list::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; } creatingTable = false; for (int i=0; iselectTable->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) { 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 (currentLog==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 = currentLog->toPlainText(); //logText = currentLog->toHtml(); 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 &line) { // if (fwbdebug) // qDebug("instDialog::addToLog: '%s'", line.toLatin1().constData()); if (line.isEmpty()) return; if (currentLog) { QString txt = line.trimmed(); QTextCharFormat format = normal_format; list::const_iterator it; for (it=error_re.begin(); it!=error_re.end(); ++it) { if ((*it).indexIn(txt) != -1) { format = error_format; break; } } for (it=warning_re.begin(); it!=warning_re.end(); ++it) { if ((*it).indexIn(txt) != -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. */ 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 = currentLog->textCursor(); cursor.insertBlock(); cursor.insertText(txt, format); //m_dialog->procLogDisplayList->addItem(txt); currentLog->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=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() { m_dialog->fwWorkList->clear(); opListMapping.clear(); Firewall * f; InstallFirewallViewItem * item; list::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::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; } void instDialog::clearReqFirewalls() { reqFirewalls.clear(); } void instDialog::addReqFirewall(Firewall *f) { reqFirewalls.insert(f); } /* * getInstOptions() fills attributes of the cnf object */ bool instDialog::getInstOptions(Firewall *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); if (inst_opt_dlg->exec()==QDialog::Rejected) { delete inst_opt_dlg; return false; } readInstallerOptionsFromDialog(fw, inst_opt_dlg); } return verifyManagementAddress(); } /* * getBatchInstOptions() fills attributes of the cnf object for batch install */ bool instDialog::getBatchInstOptions(Firewall *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); 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(): cnf.user=" << cnf.user; 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(); cnf.testRun = st->value(SETTINGS_PATH_PREFIX"/Installer/testRun").toBool(); cnf.rollback = st->value(SETTINGS_PATH_PREFIX"/Installer/rollback").toBool(); cnf.rollbackTime = st->value(SETTINGS_PATH_PREFIX"/Installer/rollbackTime").toInt(); cnf.cancelRollbackIfSuccess = st->value(SETTINGS_PATH_PREFIX"/Installer/canceRollbackIfSuccess").toBool(); } void instDialog::readInstallerOptionsFromFirewallObject(Firewall *fw) { 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 aaddr = fwopt->getStr("altAddress").c_str(); if (!aaddr.isEmpty()) cnf.maddr = aaddr; else { // 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) cnf.maddr = mgmt_addr->toString().c_str(); else cnf.maddr = ""; } /* * 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; cnf.script = FirewallInstaller::getGeneratedFileFullPath(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.useSCPForCisco = 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"); cnf.fwobj = 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 %s", aaddr.toAscii().constData()); } // 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(); cnf.testRun = dlg->m_dialog->testRun->isChecked(); cnf.rollback = dlg->m_dialog->rollback->isChecked(); cnf.rollbackTime = dlg->m_dialog->rollbackTime->value(); cnf.cancelRollbackIfSuccess = dlg->m_dialog->cancelRollbackIfSuccess->isChecked(); dlg->savePassword(); storeInstallerOptions(); } bool instDialog::verifyManagementAddress() { /* check for a common error when none or multiple interfaces are marked as * 'management' */ if (cnf.fwobj) { int nmi = 0; list 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.\n") .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 *event) { 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; } }