1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2008 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@fwbuilder.org
8 
9 
10                  Copyright (C) 2013 UNINETT AS
11 
12   Author:  Sirius Bakke <sirius.bakke@uninett.no>
13 
14   $Id$
15 
16   This program is free software which we release under the GNU General Public
17   License. You may redistribute and/or modify this program under the terms
18   of that license as published by the Free Software Foundation; either
19   version 2 of the License, or (at your option) any later version.
20 
21   This program is distributed in the hope that it will be useful,
22   but WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24   GNU General Public License for more details.
25 
26   To get a copy of the GNU General Public License, write to the Free Software
27   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 
29 */
30 
31 #include "config.h"
32 #include "global.h"
33 #include "utils.h"
34 #include "utils_no_qt.h"
35 
36 #include "instDialog.h"
37 #include "FirewallInstaller.h"
38 #include "FWBSettings.h"
39 #include "FWWindow.h"
40 #include "InstallFirewallViewItem.h"
41 #include "instOptionsDialog.h"
42 #include "instBatchOptionsDialog.h"
43 #include "FirewallCodeViewer.h"
44 
45 #include <qcheckbox.h>
46 #include <qlineedit.h>
47 #include <qtextedit.h>
48 #include <qtimer.h>
49 #include <qfiledialog.h>
50 #include <qpushbutton.h>
51 #include <qlabel.h>
52 #include <qprogressbar.h>
53 #include <qprocess.h>
54 #include <qapplication.h>
55 #include <qeventloop.h>
56 #include <qfile.h>
57 #include <qdir.h>
58 #include <qmessagebox.h>
59 #include <qspinbox.h>
60 #include <qgroupbox.h>
61 #include <qcolor.h>
62 #include <qtablewidget.h>
63 #include <qtextcodec.h>
64 #include <qfileinfo.h>
65 #include <qtextstream.h>
66 #include <qpixmapcache.h>
67 
68 #include <QPixmap>
69 #include <QDateTime>
70 #include <QTableWidget>
71 #include <QTableWidgetItem>
72 #include <QTreeWidgetItemIterator>
73 #include <QTextBlockFormat>
74 #include <QBrush>
75 #include <QTextFormat>
76 #include <QtDebug>
77 #include <QTime>
78 
79 #include "fwbuilder/Resources.h"
80 #include "fwbuilder/FWObjectDatabase.h"
81 #include "fwbuilder/Library.h"
82 #include "fwbuilder/Firewall.h"
83 #include "fwbuilder/Cluster.h"
84 #include "fwbuilder/XMLTools.h"
85 #include "fwbuilder/Interface.h"
86 #include "fwbuilder/Management.h"
87 #include "fwbuilder/StateSyncClusterGroup.h"
88 
89 #ifndef _WIN32
90 #  include <unistd.h>     // for access(2) and getdomainname
91 #endif
92 
93 #include <errno.h>
94 #include <iostream>
95 #include <algorithm>
96 
97 
98 using namespace std;
99 using namespace libfwbuilder;
100 
enableStopButton()101 void instDialog::enableStopButton()
102 {
103     currentStopButton->setText(tr("Stop"));
104     currentStopButton->setEnabled(true);
105 }
106 
disableStopButton()107 void instDialog::disableStopButton()
108 {
109     currentStopButton->setEnabled(false);
110 }
111 
checkIfNeedToCompile(Firewall * fw)112 bool instDialog::checkIfNeedToCompile(Firewall *fw)
113 {
114     return (fw->needsCompile() && !fw->getInactive());
115 }
116 
checkIfNeedToInstall(Firewall * fw)117 bool instDialog::checkIfNeedToInstall(Firewall *fw)
118 {
119     return (fw->needsInstall() && !fw->getInactive());
120 }
121 
createTreeItem(QTreeWidgetItem * parent,Firewall * fw)122 QTreeWidgetItem* instDialog::createTreeItem(QTreeWidgetItem* parent,
123                                             Firewall *fw)
124 {
125     QTreeWidgetItem* item;
126     QStringList sl;
127     sl.push_back(QString::fromUtf8(fw->getName().c_str()));
128 
129     if (parent)
130         item = new QTreeWidgetItem(parent, sl);
131     else
132         item = new QTreeWidgetItem(sl);
133 
134     QString icn_filename = (":/Icons/" + fw->getTypeName() + "/icon").c_str();
135     QPixmap pm;
136     if ( ! QPixmapCache::find(icn_filename, pm))
137     {
138         pm.load(icn_filename);
139         QPixmapCache::insert(icn_filename, pm);
140     }
141     item->setIcon(0, QIcon(pm));
142 
143     item->setData(0, Qt::UserRole, QVariant(fw->getId()));
144 
145     // Mark cluster members
146     // If parent!=NULL, new tree item corresponds to the cluster member
147     item->setData(1, Qt::UserRole, QVariant(parent!=NULL));
148 
149     // it is useful to know how many members does this cluster have. If this is
150     // not a cluster, store 0
151     list<Firewall*> members;
152     if (Cluster::isA(fw))
153         Cluster::cast(fw)->getMembersList(members);
154     int num_members = members.size();
155 
156     item->setData(2, Qt::UserRole, QVariant(num_members));
157 
158     // item->setCheckState(COMPILE_CHECKBOX_COLUMN, checkIfNeedToCompile(fw)?Qt::Checked:Qt::Unchecked);
159     // if (!compile_only)
160     //     item->setCheckState(INSTALL_CHECKBOX_COLUMN, checkIfNeedToInstall(fw)?Qt::Checked:Qt::Unchecked);
161 
162     return item;
163 }
164 
setFlags(QTreeWidgetItem * item)165 void instDialog::setFlags(QTreeWidgetItem* item)
166 {
167     int obj_id = item->data(0, Qt::UserRole).toInt();
168     Firewall *fw = Firewall::cast(project->db()->findInIndex(obj_id));
169     QTreeWidgetItem* parent = item->parent();
170 
171     time_t lm = fw->getInt("lastModified");
172     time_t lc = fw->getInt("lastCompiled");
173     time_t li = fw->getInt("lastInstalled");
174     QDateTime dt;
175 
176     if (fwbdebug)
177     {
178         qDebug() << "instDialog::setFlags"
179                  << item->text(0)
180                  << "parent=" << parent
181                  << "fw=" << fw
182                  << "Firewall::isA(fw)=" << Firewall::isA(fw)
183                  << "lm=" << lm
184                  << "lc=" << lc
185                  << "li=" << li
186                  << "compile_only=" << compile_only;
187         qDebug() << "fw->needsCompile()" << fw->needsCompile()
188                  << "checkIfNeedToCompile(fw)=" << checkIfNeedToCompile(fw);
189     }
190 
191     // need to skip the secondary cluster members if platform only
192     // allows installations on the primary (e.g. PIX).  Note that
193     // platform attribute must be the same in the cluster and member
194     // firewalls objects. See #998
195 
196     string platform = fw->getStr("platform");
197     bool install_only_on_primary_member = Resources::getTargetCapabilityBool(
198         platform, "install_only_on_primary");
199 
200     Cluster *cluster = NULL;
201     FWObject *master_interface = NULL;
202 
203     if (parent)
204     {
205         int obj_id = parent->data(0, Qt::UserRole).toInt();
206         cluster = Cluster::cast(project->db()->findInIndex(obj_id));
207         if (cluster)
208         {
209             FWObject *state_sync_group =
210                 cluster->getFirstByType(StateSyncClusterGroup::TYPENAME);
211             // use state sync group to find which member firewall is
212             // master.  This is only needed for platforms that install
213             // only on master (PIX at this time)
214             if (state_sync_group)
215             {
216                 string master_id = state_sync_group->getStr("master_iface");
217                 for (FWObjectTypedChildIterator grp_it =
218                          state_sync_group->findByType(FWObjectReference::TYPENAME);
219                      grp_it != grp_it.end(); ++grp_it)
220                 {
221                     FWObject *iface = FWObjectReference::getObject(*grp_it);
222                     if (FWObjectDatabase::getStringId(iface->getId()) == master_id)
223                     {
224                         master_interface = iface;
225                         break;
226                     }
227                 }
228             }
229         }
230     }
231 
232     // Real firewalls get checkbox for install
233     if (Firewall::isA(fw))
234     {
235         bool checked = false;
236 
237         if (!compile_only)
238         {
239             checked = checkIfNeedToInstall(fw);
240             if (cluster)
241             {
242                 // override if checkIfNeedToCompile() is true for the
243                 // parent cluster.
244                 if (checkIfNeedToCompile(cluster))
245                 {
246                     checked = true;
247                 }
248             }
249             item->setCheckState(INSTALL_CHECKBOX_COLUMN,
250                                 checked?Qt::Checked:Qt::Unchecked);
251 
252             // If this platform requires installation only on
253             // the master, disable and uncheck checkbox for the standby.
254             if (install_only_on_primary_member && master_interface != NULL)
255             {
256                 QString txt = item->text(0);
257                 if (master_interface->isChildOf(fw))
258                 {
259                     // Master
260                     item->setText(0, QString("%1 (master)").arg(txt));
261                 } else
262                 {
263                     // Standby
264                     item->setText(0, QString("%1 (standby)").arg(txt));
265                     item->setCheckState(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked);
266                     item->setFlags(0);
267                 }
268             }
269         }
270 
271         if (cluster==NULL)
272         {
273             // we are adding firewall that is not cluster member, it
274             // needs "compile" checkbox
275             checked = checkIfNeedToCompile(fw);
276             item->setCheckState(COMPILE_CHECKBOX_COLUMN,
277                                 checked?Qt::Checked:Qt::Unchecked);
278         }
279     }
280 
281     int num_members = 0;
282     // Clusters only get checkbox for compile, and only if they have members.
283     if (Cluster::isA(fw))
284     {
285         list<Firewall*> members;
286         Cluster::cast(fw)->getMembersList(members);
287         num_members = members.size();
288         if (num_members)
289         {
290             bool checked = checkIfNeedToCompile(fw);
291             item->setCheckState(COMPILE_CHECKBOX_COLUMN,
292                                 checked?Qt::Checked:Qt::Unchecked);
293         }
294     }
295 
296     dt.setTime_t(lm);
297     item->setText(LAST_MODIFIED_COLUMN, (lm)?dt.toString():QString("Never"));
298 
299     dt.setTime_t(lc);
300     item->setText(LAST_COMPILED_COLUMN, (lc)?dt.toString():QString("Never"));
301 
302     dt.setTime_t(li);
303     item->setText(LAST_INSTALLED_COLUMN, (li)?dt.toString():QString("Never"));
304 }
305 
306 /*
307  * The following color and font manipulations are subject to QT bug
308  * http://trolltech.no/developer/task-tracker/index_html?method=entry&id=212207
309  *
310  * This requires QT 4.4.1 or 4.3
311  */
setSuccessState(QTreeWidgetItem * item)312 void instDialog::setSuccessState(QTreeWidgetItem *item)
313 {
314     QBrush b = item->foreground(1);
315     b.setColor(Qt::darkGreen);
316     item->setForeground(1,b);
317     item->setForeground(0,b);
318 
319     QFont f = item->font(1);
320     f.setBold(true);
321     item->setFont(1,f);
322     item->setFont(0,f);
323 }
324 
setWarningState(QTreeWidgetItem * item)325 void instDialog::setWarningState(QTreeWidgetItem *item)
326 {
327     QBrush b = item->foreground(1);
328     b.setColor(QColor("orange"));
329     item->setForeground(1,b);
330     item->setForeground(0,b);
331 
332     QFont f = item->font(1);
333     f.setBold(true);
334     item->setFont(1,f);
335     item->setFont(0,f);
336 }
337 
setFailureState(QTreeWidgetItem * item)338 void instDialog::setFailureState(QTreeWidgetItem *item)
339 {
340     QBrush b = item->foreground(1);
341     b.setColor(Qt::darkRed);
342     item->setForeground(1,b);
343     item->setForeground(0,b);
344 
345     QFont f = item->font(1);
346     f.setBold(true);
347     item->setFont(1,f);
348     item->setFont(0,f);
349 }
350 
setErrorState(QTreeWidgetItem * item)351 void instDialog::setErrorState(QTreeWidgetItem *item)
352 {
353     QBrush b = item->foreground(1);
354     b.setColor(Qt::darkRed);
355     item->setForeground(1,b);
356     item->setForeground(0,b);
357 
358     QFont f = item->font(1);
359     f.setBold(true);
360     item->setFont(1,f);
361     item->setFont(0,f);
362 }
363 
setInProcessState(QTreeWidgetItem * item)364 void instDialog::setInProcessState(QTreeWidgetItem *item)
365 {
366     QBrush b = item->foreground(1);
367     b.setColor(Qt::black);
368     item->setForeground(1,b);
369     item->setForeground(0,b);
370 
371     QFont f = item->font(1);
372     f.setBold(true);
373     item->setFont(1,f);
374     item->setFont(0,f);
375 }
376 
opSuccess(Firewall * fw)377 void instDialog::opSuccess(Firewall *fw)
378 {
379     if (fwbdebug)
380         qDebug() << "instDialog::opSuccess fw=" << fw->getName().c_str();
381 
382     compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_SUCCESS;
383     QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
384     if (itm)
385     {
386         itm->setText(1,tr("Success"));
387         setSuccessState(itm);
388     }
389     currentLabel->setText("");
390 }
391 
opWarning(Firewall * fw)392 void instDialog::opWarning(Firewall *fw)
393 {
394     if (fwbdebug)
395         qDebug() << "instDialog::opWarning fw=" << fw->getName().c_str();
396 
397     compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_WARNING;
398     QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
399     if (itm)
400     {
401         itm->setText(1,tr("Success with warning"));
402         setWarningState(itm);
403     }
404     currentLabel->setText("");
405 }
406 
opError(Firewall * fw)407 void instDialog::opError(Firewall *fw)
408 {
409     if (fwbdebug)
410         qDebug() << "instDialog::opError fw=" << fw->getName().c_str();
411 
412     compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_ERROR;
413     QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
414     if (itm)
415     {
416         itm->setText(1, tr("Error"));
417         setErrorState(itm);
418     }
419     currentLabel->setText("");
420 }
421 
opCancelled(Firewall * fw)422 void instDialog::opCancelled(Firewall *fw)
423 {
424     compile_status[fw] = fwcompiler::BaseCompiler::FWCOMPILER_ERROR;
425     QTreeWidgetItem* itm = opListMapping[(fw)->getId()];
426     // itm can be NULL, for example when we install to PIX cluster
427     // where we skip one of the members
428     if (itm)
429     {
430         itm ->setText(1, tr("Cancelled"));
431         setErrorState(itm);
432     }
433     currentLabel->setText("");
434 }
435 
nextClicked()436 void instDialog::nextClicked()
437 {
438     if (currentPage() == CHOOSE_OBJECTS)
439     {
440         page_1_op = INST_DLG_COMPILE;
441         showPage(COMPILE_INSTALL);
442         return;
443     }
444 
445     if (currentPage() == COMPILE_INSTALL &&
446         (page_1_op == INST_DLG_COMPILE || page_1_op == INST_DLG_INSPECT))
447     {
448         // clicking "Next" on page 1 (compile/install) changes
449         // contents of the same page
450         page_1_op = INST_DLG_INSTALL;
451         showPage(COMPILE_INSTALL);
452         return;
453     }
454 }
455 
backClicked()456 void instDialog::backClicked()
457 {
458     if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_COMPILE)
459     {
460         // clicking "Back" on page 1 in mode "compile" returns to page 0
461         page_1_op = INST_DLG_COMPILE;
462         showPage(CHOOSE_OBJECTS);
463         return;
464     }
465 
466     if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_INSTALL)
467     {
468         // clicking "Back" on page 1 in mode "install" changes
469         // contents of the same page.  Ideally, I would like to be
470         // able to move back from "install" mode to "compile" mode
471         // without recompiling everything. This is impossible in the
472         // current implementation because we reuse the same widgets on
473         // the page.  This will be possible when "install" becomes its
474         // own page of the wizard.
475 
476         // page_1_op = INST_DLG_COMPILE;
477         // showPage(COMPILE_INSTALL);
478         return;
479     }
480 
481     if (currentPage() == COMPILE_INSTALL && page_1_op == INST_DLG_INSPECT)
482     {
483         page_1_op = INST_DLG_COMPILE;
484         showPage(COMPILE_INSTALL);
485         return;
486     }
487 }
488 
inspectFiles()489 void instDialog::inspectFiles()
490 {
491     page_1_op = INST_DLG_INSPECT;
492     showPage(COMPILE_INSTALL);
493 }
494 
prepareInstConf(Firewall *)495 void instDialog::prepareInstConf(Firewall *)
496 {
497     if (fwbdebug) qDebug("instDialog::prepareInstConf");
498 }
499 
storeInstallerOptions()500 void instDialog::storeInstallerOptions()
501 {
502     st->setValue(SETTINGS_PATH_PREFIX"/Installer/savediff",cnf.save_diff);
503     st->setValue(SETTINGS_PATH_PREFIX"/Installer/saveStandby",cnf.saveStandby);
504     st->setValue(SETTINGS_PATH_PREFIX"/Installer/dryrun"  ,cnf.dry_run);
505     st->setValue(SETTINGS_PATH_PREFIX"/Installer/quiet",   cnf.quiet);
506     st->setValue(SETTINGS_PATH_PREFIX"/Installer/verbose", cnf.verbose);
507     st->setValue(SETTINGS_PATH_PREFIX"/Installer/stripComments", cnf.stripComments);
508     st->setValue(SETTINGS_PATH_PREFIX"/Installer/compressScript", cnf.compressScript);
509     st->setValue(SETTINGS_PATH_PREFIX"/Installer/copyFWB",  cnf.copyFWB);
510 }
511 
summary()512 void instDialog::summary()
513 {
514     QStringList str;
515 
516     str.append(QObject::tr("Summary:"));
517     str.append(QObject::tr("* Running as user : %1").arg(user_name));
518     str.append(QObject::tr("* Firewall name : %1")
519                .arg(QString::fromUtf8(cnf.fwobj->getName().c_str())));
520     str.append(QObject::tr("* Installer uses user name : %1").arg(cnf.user));
521 
522     // print destination machine address or name correctly, taking into
523     // account putty session if any
524     if (!cnf.putty_session.isEmpty())
525         str.append(QObject::tr("* Using putty session: %1").arg(cnf.putty_session));
526     else
527         str.append(QObject::tr("* Management address : %1").arg(cnf.maddr));
528 
529     str.append(QObject::tr("* Platform : %1")
530               .arg(cnf.fwobj->getStr("platform").c_str()));
531     str.append(QObject::tr("* Host OS : %1")
532               .arg(cnf.fwobj->getStr("host_OS").c_str()));
533     str.append(QObject::tr("* Loading configuration from file %1")
534               .arg(cnf.fwbfile));
535 
536     if (cnf.save_diff)
537         str.append(QObject::tr("* Configuration diff will be saved in file %1").
538                    arg(cnf.diff_file));
539 
540     if (cnf.dry_run)
541         str.append(QObject::tr("* Commands will not be executed on the firewall"));
542 
543     if (fwbdebug)
544     {
545         str.append(QObject::tr("--------------------------------"));
546         str.append(QObject::tr("* Variables:"));
547         str.append(QObject::tr("* fwdir= %1") .arg(cnf.fwdir));
548         str.append(QObject::tr("* fwscript= %1") .arg(cnf.fwscript));
549         str.append(QObject::tr("* remote_script= %1") .arg(cnf.remote_script));
550     }
551 
552     str.append("");
553 
554     QTextCursor cursor = m_dialog->procLogDisplay->textCursor();
555     cursor.insertBlock();
556     cursor.insertText(str.join("\n"), highlight_format);
557 }
558 
fillCompileSelectList()559 void instDialog::fillCompileSelectList()
560 {
561     if (fwbdebug) qDebug("instDialog::fillCompileSelectList");
562 
563     Firewall *fw;
564     Cluster *cl;
565     QDateTime dt;
566 
567     creatingTable = true;
568     m_dialog->selectTable->clear();
569 
570     list<Firewall*> working_list_of_firewalls = firewalls;
571 
572     for (list<Cluster *>::iterator i=clusters.begin(); i!=clusters.end(); ++i)
573     {
574         cl = *i;
575 
576         QTreeWidgetItem* cluster_item = createTreeItem(NULL, cl);
577         m_dialog->selectTable->addTopLevelItem(cluster_item);
578 
579         list<Firewall*> members;
580         cl->getMembersList(members);
581 
582         for (list<Firewall*>::iterator member=members.begin();
583              member!=members.end(); ++member)
584         {
585             createTreeItem(cluster_item, *member);
586             working_list_of_firewalls.remove(*member);
587         }
588         cluster_item->setExpanded(true);
589     }
590 
591     for (list<Firewall *>::iterator i=working_list_of_firewalls.begin();
592          i!=working_list_of_firewalls.end(); ++i)
593     {
594         fw = *i;
595         QTreeWidgetItem* fw_item = createTreeItem(NULL, fw);
596         m_dialog->selectTable->addTopLevelItem(fw_item);
597     }
598 
599     QTreeWidgetItemIterator it(m_dialog->selectTable);
600     while (*it)
601     {
602         setFlags(*it);
603         ++it;
604     }
605 
606 
607     /* ticket #1305
608      * check if any of the firewall objects are members of clusters but
609      * the clusters are not requested for compile
610      */
611 
612     QString warn1(
613         tr("<b>You are trying to compile policy for a firewall object that is "
614            "a member of a cluster, however you requested compilation of only "
615            "this member firewall and not the cluster it belongs to. Assuming "
616            "firewall is standalone and not cluster member. Rules and parts of "
617            "the script specific for the cluster configuration will not be "
618            "generated.</b>"));
619 
620     QStringList warn2;
621 
622     list<FWObject*> all_libs = project->db()->getByType(Library::TYPENAME);
623     foreach(FWObject *lib, all_libs)
624     {
625         if (lib->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) continue;
626         list<FWObject*> all_clusters = lib->getByTypeDeep(Cluster::TYPENAME);
627         foreach(FWObject *_cl, all_clusters)
628         {
629             if (std::find(clusters.begin(), clusters.end(), _cl) == clusters.end())
630             {
631                 Cluster *cluster = Cluster::cast(_cl);
632                 assert(cluster);
633                 foreach(FWObject *fw, firewalls)
634                 {
635                     if (cluster->hasMember(Firewall::cast(fw)))
636                     {
637                         warn2 <<
638                             QString(tr("Firewall '%1' is member of cluster '%2'")
639                                     .arg(QString::fromUtf8(fw->getName().c_str()))
640                                     .arg(QString::fromUtf8(cluster->getPath().c_str())));
641                     }
642                 }
643             }
644         }
645     }
646 
647     if (!warn2.empty())
648     {
649         m_dialog->warning_message_1->setText(warn1);
650         m_dialog->warning_message_2->setText(warn2.join("\n"));
651         m_dialog->warning_space->show();
652     }
653 
654     creatingTable = false;
655 
656     for (int i=0; i<m_dialog->selectTable->columnCount(); i++)
657         m_dialog->selectTable->resizeColumnToContents(i);
658 
659     setNextEnabled(0, tableHasCheckedItems());
660     //m_dialog->selectTable->resizeRowsToContents();
661 }
662 
displayCommand(const QStringList & args)663 void instDialog::displayCommand(const QStringList &args)
664 {
665     QStringList a1 = args;
666 
667     for (QStringList::iterator i=a1.begin(); i!=a1.end(); i++)
668     {
669         if ( (*i)=="-pw" )
670         {
671             i++;
672             *i = "XXXXXX";
673             break;
674         }
675     }
676     QString s=a1.join(" ");
677     addToLog( tr("Running command '%1'\n").arg(s) );
678 }
679 
updateProgressBar(int n,bool setsize)680 void instDialog::updateProgressBar(int n, bool setsize)
681 {
682     if (fwbdebug)
683         qDebug("instDialog::updateProgressBar  n=%d setsize=%d",n,setsize);
684 
685     if (setsize) currentProgressBar->setMaximum(n);
686     else
687         currentProgressBar->setValue(currentProgressBar->maximum()-n);
688 }
689 
finishClicked()690 void instDialog::finishClicked()
691 {
692     finished = true;
693     accept();
694 }
695 
696 /* user clicked 'Cancel' */
cancelClicked()697 void instDialog::cancelClicked()
698 {
699     if (fwbdebug) qDebug("instDialog::cancelClicked()");
700     finished = true;
701 
702     if (proc.state() == QProcess::Running)
703     {
704         if (fwbdebug)
705             qDebug() << "instDialog::cancelClicked  killing background process";
706         rejectDialogFlag = true;
707         proc.kill();
708     }
709 
710     if (installer != NULL)
711     {
712         if (fwbdebug)
713             qDebug() << "instDialog::cancelClicked  killing installer";
714         installer->terminate();
715         delete installer;
716         installer = NULL;
717     }
718 
719     QDialog::reject();
720 }
721 
722 
showEvent(QShowEvent * ev)723 void instDialog::showEvent( QShowEvent *ev)
724 {
725     st->restoreGeometry(this, QRect(200,100,780,500) );
726     QDialog::showEvent(ev);
727 }
728 
hideEvent(QHideEvent * ev)729 void instDialog::hideEvent( QHideEvent *ev)
730 {
731     st->saveGeometry(this);
732     QDialog::hideEvent(ev);
733 }
734 
saveLog()735 void instDialog::saveLog()
736 {
737     /*
738      * We use QTextEdit::append to add lines to the log buffer, each
739      append creates a new paragraph so QTextEdit::text returns only
740      contents of the last paragraph. Need to reassemble the whole text
741      adding text from each paragraph separately.
742      */
743     QString logText;
744     logText = m_dialog->procLogDisplay->toPlainText();
745 
746     QString s = QFileDialog::getSaveFileName(
747                     this,
748                     "Choose a file",
749                     st->getOpenFileDir(),
750                     "Text file (*.txt)");
751 
752     if (s.isEmpty()) return;
753     st->setOpenFileDir(s);
754 
755     if (!s.endsWith(".txt")) s += ".txt";
756     if (fwbdebug)
757 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
758         qDebug( "Saving log to file %s", s.toAscii().constData() );
759 #else
760         qDebug( "Saving log to file %s", s.toLatin1().constData() );
761 #endif
762 
763     QFile f(s);
764     if (f.open( QIODevice::WriteOnly ))
765     {
766         QTextStream str( &f );
767         str << logText;
768         f.close();
769     }
770 }
771 
772 /*
773  * Adds one line of text to the log
774  *
775  */
addToLog(const QString & buf)776 void instDialog::addToLog(const QString &buf)
777 {
778     if (buf.isEmpty()) return;
779 
780     foreach(QString line, buf.trimmed().split("\n"))
781     {
782         QTextCharFormat format = normal_format;
783 
784         list<QRegExp>::const_iterator it;
785         for (it=error_re.begin(); it!=error_re.end(); ++it)
786         {
787             if ((*it).indexIn(line) != -1)
788             {
789                 format = error_format;
790                 break;
791             }
792         }
793 
794         for (it=warning_re.begin(); it!=warning_re.end(); ++it)
795         {
796             if ((*it).indexIn(line) != -1)
797             {
798                 format = warning_format;
799                 break;
800             }
801         }
802 
803         /* See sourceforge bug https://sourceforge.net/tracker/?func=detail&aid=2847263&group_id=5314&atid=1070394
804          *
805          * QTextEditor::insertHtml() becomes incrementally slow as the
806          * amount of text already in the QTextEditor
807          * increases. Compiling ~10 firewalls with few dozen rules
808          * each slows the output to a crawl on Windows.  Keeping each
809          * line in a separate block makes it much faster.
810          */
811 
812         QString txt = line;
813         while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r")))
814             txt.chop(1);
815 
816         if (format == error_format || format == warning_format )
817             format.setAnchorHref(txt);
818 
819         QTextCursor cursor = m_dialog->procLogDisplay->textCursor();
820 
821         cursor.insertBlock();
822 
823         cursor.insertText(txt, format);
824     }
825 
826     //m_dialog->procLogDisplayList->addItem(txt);
827 
828     m_dialog->procLogDisplay->ensureCursorVisible();
829 
830     //qApp->processEvents();
831 }
832 
interpretLogLine(const QString & line)833 void instDialog::interpretLogLine(const QString &line)
834 {
835     if (fwbdebug)
836 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
837         qDebug("instDialog::interpretLogLine %s", line.toAscii().constData() );
838 #else
839         qDebug("instDialog::interpretLogLine %s", line.toLatin1().constData() );
840 #endif
841 
842     QStringList words = line.trimmed().split(" ");
843 
844     if (fwbdebug)
845     {
846         for (int i=0; i<words.size(); ++i)
847 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
848             qDebug("instDialog::interpretLogLine words[%d]='%s'",
849                    i, words[i].toAscii().constData());
850 #else
851             qDebug("instDialog::interpretLogLine words[%d]='%s'",
852                    i, words[i].toLatin1().constData());
853 #endif
854     }
855 
856     if (words.first().indexOf("rule")>=0)
857     {
858         bool ok;
859         processedRules = words[1].toInt(&ok);
860         if (ok)
861             currentProgressBar->setValue(processedRules);
862 
863         if (fwbdebug)
864             qDebug("instDialog::interpretLogLine set progress bar current=%d",
865                    processedRules);
866     } else
867     {
868         if (words.first().indexOf("processing")>=0)
869         {
870             currentProgressBar->reset();
871             bool ok;
872             int totalRules = words[1].toInt(&ok);
873             if (ok)
874                 currentProgressBar->setMaximum(totalRules);
875             processedRules = 0;
876 
877             if (fwbdebug)
878                 qDebug("instDialog::interpretLogLine set progress bar max=%d",
879                        totalRules);
880         } else
881         {
882             if (words.first().indexOf("Compiling")>=0)
883             {
884                 //currentLabel->setText(line.trimmed());
885                 currentProgressBar->reset();
886             } else
887             {
888                 if (line.indexOf("Compiled successfully")>=0)
889                 {
890                     //currentLabel->setText(line.trimmed());
891                     currentProgressBar->setValue(currentProgressBar->maximum());
892                     if (fwbdebug)
893                         qDebug("instDialog::interpretLogLine set progress "
894                                "bar to max");
895                 }
896             }
897         }
898     }
899     QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,1);
900 }
901 
readFromStdout()902 void instDialog::readFromStdout()
903 {
904     char buf[2048];
905     int read_status = 0;
906     while ((read_status = proc.readLine(buf, sizeof(buf)))>0)
907     {
908         if (fwbdebug)
909         {
910             qDebug("instDialog::readFromStdout: read_status=%d buf=%s",
911                    read_status, buf);
912         }
913         addToLog(buf);
914         interpretLogLine(buf);
915     }
916 }
917 
selectAllFirewalls()918 void instDialog::selectAllFirewalls()
919 {
920     if (fwbdebug) qDebug("instDialog::selectAllFirewalls");
921     setSelectStateAll(INSTALL_CHECKBOX_COLUMN, Qt::Checked);
922     setSelectStateAll(COMPILE_CHECKBOX_COLUMN, Qt::Checked);
923     tableItemChanged(NULL, 0);
924 }
925 
deselectAllFirewalls()926 void instDialog::deselectAllFirewalls()
927 {
928     setSelectStateAll(INSTALL_CHECKBOX_COLUMN, Qt::Unchecked);
929     setSelectStateAll(COMPILE_CHECKBOX_COLUMN, Qt::Unchecked);
930     tableItemChanged(NULL, 0);
931 }
932 
setSelectStateAll(int column,Qt::CheckState select)933 void instDialog::setSelectStateAll(int column, Qt::CheckState select)
934 {
935     QTreeWidgetItemIterator it(m_dialog->selectTable);
936     while (*it)
937     {
938         int obj_id = (*it)->data(0, Qt::UserRole).toInt();
939         FWObject *o = project->db()->findInIndex(obj_id);
940         bool cluster_member = (*it)->data(1, Qt::UserRole).toBool();
941         int num_members = (*it)->data(2, Qt::UserRole).toInt();
942 
943         Qt::ItemFlags flags = (*it)->flags();
944         if ((flags & Qt::ItemIsUserCheckable) != 0)
945         {
946             // firewalls only get checkboxes for install,
947             if (column == INSTALL_CHECKBOX_COLUMN && Firewall::isA(o))
948                 (*it)->setCheckState(column, select);
949 
950             // Cluster gets checkbox for compile.
951             // Cluster should never get a checkbox if it has no members.
952             // Firewall that is not a cluster member gets compile checkbox
953             if ((column == COMPILE_CHECKBOX_COLUMN && Cluster::isA(o) && num_members) ||
954                 (Firewall::isA(o) && !cluster_member))
955                 (*it)->setCheckState(column, select);
956         }
957         ++it;
958     }
959 }
960 
fillCompileOpList()961 void instDialog::fillCompileOpList()
962 {
963     compile_fw_list.clear();
964     QTreeWidgetItemIterator it(m_dialog->selectTable);
965     while (*it)
966     {
967         if ((*it)->checkState(COMPILE_CHECKBOX_COLUMN))
968         {
969             int obj_id = (*it)->data(0, Qt::UserRole).toInt();
970             FWObject *o = project->db()->findInIndex(obj_id);
971             compile_fw_list.push_back(Firewall::cast(o));
972         }
973         ++it;
974     }
975     compile_list_initial_size = compile_fw_list.size();
976 }
977 
fillCompileUIList()978 void instDialog::fillCompileUIList()
979 {
980     if (fwbdebug) qDebug("instDialog::fillCompileUIList");
981 
982     m_dialog->fwWorkList->clear();
983     opListMapping.clear();
984 
985     Firewall * f;
986     InstallFirewallViewItem * item;
987     list<Firewall*>::iterator i;
988     for(i=compile_fw_list.begin(); i!=compile_fw_list.end(); ++i)
989     {
990         f = (*i);
991         item = new InstallFirewallViewItem(
992             NULL,//m_dialog->fwWorkList,
993             QString::fromUtf8(f->getName().c_str()),
994             false);
995 
996         item->setData(0, Qt::UserRole, QVariant(f->getId()));
997         m_dialog->fwWorkList->insertTopLevelItem(0, item);
998 
999         opListMapping[f->getId()] = item;
1000     }
1001 
1002     m_dialog->fwWorkList->resizeColumnToContents(0);
1003     m_dialog->fwWorkList->sortByColumn(0, Qt::AscendingOrder);
1004 }
1005 
fillInstallOpList()1006 void instDialog::fillInstallOpList()
1007 {
1008     if (fwbdebug) qDebug("instDialog::fillInstallOpList");
1009     install_fw_list.clear();
1010     QTreeWidgetItemIterator it(m_dialog->selectTable);
1011     while (*it)
1012     {
1013         if ((*it)->checkState(INSTALL_CHECKBOX_COLUMN))
1014         {
1015             int obj_id = (*it)->data(0, Qt::UserRole).toInt();
1016             FWObject *o = project->db()->findInIndex(obj_id);
1017             install_fw_list.push_back(Firewall::cast(o));
1018             if (fwbdebug)
1019                 qDebug("fillInstallOpList: Install requested for %s", o->getName().c_str());
1020         }
1021         ++it;
1022     }
1023     install_list_initial_size = install_fw_list.size();
1024 }
1025 
fillInstallUIList()1026 void instDialog::fillInstallUIList()
1027 {
1028     if (fwbdebug) qDebug("instDialog::fillInstallUIList");
1029 
1030     m_dialog->fwWorkList->clear();
1031     opListMapping.clear();
1032 
1033     Firewall * f;
1034     InstallFirewallViewItem * item;
1035     list<Firewall*>::iterator i;
1036     for(i=install_fw_list.begin(); i!=install_fw_list.end(); ++i)
1037     {
1038         f = (*i);
1039         item = new InstallFirewallViewItem(
1040             NULL,
1041             QString::fromUtf8(f->getName().c_str()),
1042             false);
1043 
1044         m_dialog->fwWorkList->insertTopLevelItem(0, item);
1045         opListMapping[f->getId()] = item;
1046     }
1047     m_dialog->fwWorkList->resizeColumnToContents(0);
1048     m_dialog->fwWorkList->sortByColumn(0, Qt::AscendingOrder);
1049 }
1050 
findFirewallInCompileLog(QTreeWidgetItem * item)1051 void instDialog::findFirewallInCompileLog(QTreeWidgetItem* item)
1052 {
1053     if (fwbdebug) qDebug("instDialog::findFirewallInCompileLog");
1054 
1055     m_dialog->detailMCframe->show();
1056     qApp->processEvents();
1057     QString fw_name = item->text(0);
1058 
1059     m_dialog->procLogDisplay->moveCursor( QTextCursor::End );
1060     m_dialog->procLogDisplay->find(currentSearchString +
1061             fw_name,
1062             QTextDocument::FindWholeWords |
1063             QTextDocument::FindCaseSensitively |
1064             QTextDocument::FindBackward);
1065 }
1066 
tableItemChanged(QTreeWidgetItem *,int)1067 void instDialog::tableItemChanged(QTreeWidgetItem*, int)
1068 {
1069     if (!creatingTable)
1070         setNextEnabled(0, tableHasCheckedItems());
1071 }
1072 
tableHasCheckedItems()1073 bool instDialog::tableHasCheckedItems()
1074 {
1075     QTreeWidgetItemIterator it(m_dialog->selectTable);
1076     while (*it)
1077     {
1078         if ((*it)->checkState(COMPILE_CHECKBOX_COLUMN) ||
1079             (*it)->checkState(INSTALL_CHECKBOX_COLUMN))
1080             return true;
1081         ++it;
1082     }
1083     return false;
1084 }
1085 
1086 /*
1087  * getInstOptions() fills attributes of the cnf object
1088  */
getInstOptions(Firewall * fw,bool installing_many_firewalls)1089 bool instDialog::getInstOptions(Firewall *fw, bool installing_many_firewalls)
1090 {
1091     if (fwbdebug)
1092         qDebug() << "instDialog::getInstOptions() begin"
1093                  << "cnf.user=" << cnf.user
1094                  << "cnf.maddr=" << cnf.maddr
1095                  << "fw=" << fw;
1096 
1097     cnf.fwobj = fw;
1098 
1099     readInstallerOptionsFromSettings();
1100     readInstallerOptionsFromFirewallObject(fw);
1101 
1102     if (inst_opt_dlg && inst_opt_dlg->m_dialog->batchInstall->isChecked())
1103     {
1104         // in batch install mode we use the same dialog to fill cnf
1105         // without showing it to the user again
1106         readInstallerOptionsFromDialog(fw, inst_opt_dlg);
1107     } else
1108     {
1109         // In non-batch mode installer options from the dialog
1110         // overwrite options set in the fw object itself.
1111         if (inst_opt_dlg) delete inst_opt_dlg;
1112         inst_opt_dlg = new instOptionsDialog(this, &cnf, installing_many_firewalls);
1113 
1114         int resultCode = inst_opt_dlg->exec();
1115 
1116         // 0 - rejected
1117         // 1 - accepted
1118         // -1 - cancell all clicked
1119         if (resultCode == -1)
1120         {
1121             canceledAll = true;
1122             delete inst_opt_dlg;
1123             inst_opt_dlg = NULL;
1124             return false;
1125         }
1126 
1127         if (resultCode == QDialog::Rejected)
1128         {
1129             delete inst_opt_dlg;
1130             inst_opt_dlg = NULL;
1131             return false;
1132         }
1133 
1134         readInstallerOptionsFromDialog(fw, inst_opt_dlg);
1135 
1136         inst_opt_dlg->close();
1137         // do not delete the dialog because we may need to get data from it again if
1138         // in batch install mode.
1139         //inst_opt_dlg->deleteLater();
1140     }
1141 
1142     if (fwbdebug)
1143         qDebug() << "instDialog::getInstOptions() end"
1144                  << "cnf.user=" << cnf.user
1145                  << "cnf.maddr=" << cnf.maddr;
1146 
1147     return verifyManagementAddress();
1148 }
1149 
readInstallerOptionsFromSettings()1150 void instDialog::readInstallerOptionsFromSettings()
1151 {
1152     if (fwbdebug) qDebug("instDialog::readInstallerOptionsFromSettings");
1153 
1154     fwb_prompt="--**--**--";
1155 
1156     cnf.save_diff = st->value(SETTINGS_PATH_PREFIX"/Installer/savediff").toBool();
1157     cnf.saveStandby = st->value(SETTINGS_PATH_PREFIX"/Installer/saveStandby").toBool();
1158     cnf.dry_run = st->value(SETTINGS_PATH_PREFIX"/Installer/dryrun").toBool();
1159     cnf.quiet = st->value(SETTINGS_PATH_PREFIX"/Installer/quiet").toBool();
1160     cnf.verbose = st->value(SETTINGS_PATH_PREFIX"/Installer/verbose" ).toBool();
1161     cnf.stripComments  = st->value(SETTINGS_PATH_PREFIX"/Installer/stripComments").toBool();
1162     cnf.compressScript = st->value(SETTINGS_PATH_PREFIX"/Installer/compressScript").toBool();
1163     cnf.copyFWB = st->value(SETTINGS_PATH_PREFIX"/Installer/copyFWB").toBool();
1164 }
1165 
readInstallerOptionsFromFirewallObject(Firewall * fw)1166 void instDialog::readInstallerOptionsFromFirewallObject(Firewall *fw)
1167 {
1168     if (fwbdebug)
1169         qDebug() << "instDialog::readInstallerOptionsFromFirewallObject"
1170                  << "fw=" << fw
1171                  << QString( (fw) ? QString::fromUtf8(fw->getName().c_str()) : "");
1172 
1173     FWOptions *fwopt = NULL;
1174     if (fw)
1175     {
1176         fwopt = fw->getOptionsObject();
1177 
1178         string platform = cnf.fwobj->getStr("platform");
1179         string host_OS = cnf.fwobj->getStr("host_OS");
1180 
1181         cnf.user = fwopt->getStr("admUser").c_str();
1182 
1183         QString standard_management_addr;
1184         // Note that Host::getManagementAddress() scans interfaces and
1185         // finds one marked as "management" and takes its address.
1186         // It does not use Management child object.
1187         const InetAddr *mgmt_addr = cnf.fwobj->getManagementAddress();
1188         if (mgmt_addr)
1189             standard_management_addr = mgmt_addr->toString().c_str();
1190         else
1191             standard_management_addr = "";
1192 
1193         QString aaddr = fwopt->getStr("altAddress").c_str();
1194 
1195         if (fwbdebug)
1196             qDebug() << "    standard_management_addr="
1197                      << standard_management_addr
1198                      << "aaddr=" << aaddr;
1199 
1200         if (!aaddr.isEmpty()) cnf.maddr = aaddr;
1201         else cnf.maddr = standard_management_addr;
1202 
1203         cnf.putty_session = "";
1204 
1205 #ifdef _WIN32
1206 
1207 /*
1208  * See #1724. There is a problem with pscp.exe and putty
1209  * sessions. Plink.exe accepts session name in place of the host name
1210  * on the command line, but pscp.exe does not. We ask user to enter
1211  * session name in the "alternative name or address to use to
1212  * communicate with the firewall" input field in the "Installer" tab
1213  * of the firewall settings dialog and then use it in place of the
1214  * host name in the command line for pscp.exe and plink.exe. This
1215  * works with plink.exe but breaks pscp.exe which interprets it as a
1216  * host name and fails with an error ""ssh_init: Host does not exist".
1217  *
1218  * Will try to determine if what user entered in the "alternative host
1219  * or address field" is a session name and use different command line
1220  * for pscp.exe
1221  *
1222  *
1223  * HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\<session_name>
1224  */
1225 
1226         QSettings putty_reg(QSettings::UserScope, "SimonTatham", "PuTTY\\Sessions");
1227         QStringList sessions = putty_reg.childGroups();
1228 
1229         if (fwbdebug)
1230         {
1231             qDebug() << putty_reg.fileName();
1232             qDebug() << "found " << sessions.size() << " putty sessions";
1233             foreach(QString key, sessions)
1234             {
1235                 qDebug() << "putty session " << key;
1236             }
1237         }
1238 
1239         if (sessions.contains(aaddr))
1240         {
1241             if (fwbdebug)
1242                 qDebug() << "Found matching putty session" << aaddr;
1243             cnf.maddr = standard_management_addr;
1244             cnf.putty_session = aaddr;
1245         }
1246 
1247 #endif
1248 
1249 
1250         /*
1251          * if user requested test run, store firewall script in a temp
1252          * file.  Always store it in a temp file on linksys
1253          */
1254         QString s;
1255 
1256         /* user_can_change_install_dir */
1257         bool uccid = Resources::getTargetOptionBool(
1258             host_OS, "user_can_change_install_dir");
1259 
1260         if (uccid) s = fwopt->getStr("firewall_dir").c_str();
1261 
1262         if (s.isEmpty()) s = Resources::getTargetOptionStr(
1263             host_OS, "activation/fwdir").c_str();
1264 
1265         cnf.fwdir = s;
1266 
1267         /*
1268          * Generated files should be saved in the same directory where
1269          * the .fwb file is located, except if user specified full path
1270          * in the advaced settings dialog.
1271          */
1272         cnf.script = FirewallInstaller::getGeneratedFileFullPath(fw);
1273 //        cnf.script = FirewallInstaller::getGeneratedFileName(fw);
1274         cnf.remote_script = ""; // filled in FirewallInstaller::readManifest()
1275         cnf.fwbfile = project->db()->getFileName().c_str();
1276         cnf.wdir = getFileDir( project->getRCS()->getFileName() );
1277         cnf.diff_file = QString(cnf.fwobj->getName().c_str())+".diff";
1278         cnf.diff_pgm = Resources::platform_res[platform]->
1279             getResourceStr("/FWBuilderResources/Target/diff").c_str();
1280 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1281         cnf.diff_pgm = getPathToBinary(
1282             cnf.diff_pgm.toAscii().constData()).c_str();
1283 #else
1284         cnf.diff_pgm = getPathToBinary(
1285             cnf.diff_pgm.toLatin1().constData()).c_str();
1286 #endif
1287 #ifdef _WIN32
1288         cnf.diff_pgm = cnf.diff_pgm + ".exe";
1289 #endif
1290         cnf.sshArgs = fwopt->getStr("sshArgs").c_str();
1291         cnf.scpArgs = fwopt->getStr("scpArgs").c_str();
1292         cnf.useSCPForRouter = fwopt->getBool("use_scp");
1293         cnf.useNXOSSession = fwopt->getBool("use_nxos_session");
1294 
1295 
1296         cnf.activationCmd = fwopt->getStr("activationCmd").c_str();
1297 
1298         if (fwbdebug)
1299         {
1300             qDebug("platform: %s", platform.c_str());
1301             qDebug("host_OS: %s", host_OS.c_str());
1302             qDebug("user_can_change_install_dir=%d", uccid);
1303             qDebug("firewall_dir='%s'", fwopt->getStr("firewall_dir").c_str());
1304 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1305             qDebug("management address: %s", cnf.maddr.toAscii().constData());
1306             qDebug("cnf.fwdir='%s'", cnf.fwdir.toAscii().constData());
1307             qDebug("activationCmd='%s'", cnf.activationCmd.toAscii().constData());
1308 #else
1309             qDebug("management address: %s", cnf.maddr.toLatin1().constData());
1310             qDebug("cnf.fwdir='%s'", cnf.fwdir.toLatin1().constData());
1311             qDebug("activationCmd='%s'", cnf.activationCmd.toLatin1().constData());
1312 #endif
1313         }
1314 
1315     }
1316 }
1317 
readInstallerOptionsFromDialog(Firewall * fw,instOptionsDialog * dlg)1318 void instDialog::readInstallerOptionsFromDialog(Firewall *fw,
1319                                                 instOptionsDialog *dlg)
1320 {
1321     if (fwbdebug)
1322         qDebug() << "instDialog::readInstallerOptionsFromDialog"
1323                  << "fw=" << fw;
1324 
1325     QString adm_user;
1326 
1327     FWOptions *fwopt = NULL;
1328     if (fw)
1329     {
1330         fwopt = cnf.fwobj->getOptionsObject();
1331         adm_user = fwopt->getStr("admUser").c_str();
1332     }
1333 
1334     cnf.batchInstall = dlg->m_dialog->batchInstall->isChecked();
1335 
1336     cnf.dry_run     = dlg->m_dialog->test->isChecked();
1337     cnf.backup_file = dlg->m_dialog->backupConfigFile->text();
1338     cnf.backup      = !cnf.backup_file.isEmpty();
1339     cnf.save_diff   = dlg->m_dialog->saveDiff->isChecked();
1340     cnf.saveStandby = dlg->m_dialog->saveStandby->isChecked();
1341 
1342 /* Alternative address:
1343     - first, check dialog. User could have overriden it using dialog
1344     - then check firewall options, user could have set it in the "Install"
1345       tab of firewall settings dialog
1346     - last, if all overrides are empty, take it from the management interface
1347 
1348     - ignore alternative address if in batch mode
1349  */
1350 
1351     if ( ! cnf.batchInstall)
1352     {
1353         QString aaddr = dlg->m_dialog->altAddress->text();
1354         if (!aaddr.isEmpty())
1355         {
1356 /* alternative address can also be putty session name. In any case,
1357  * leave it up to ssh to resolve it and signal an error if it can't be
1358  * resolved ( Putty session name does not have to be in DNS at all ).
1359  */
1360             cnf.maddr = aaddr;
1361             if (fwbdebug)
1362                 qDebug() << "alternative addr:" << aaddr;
1363         }
1364     }
1365 
1366     // user name set in the dialog overrides that set in the fw object
1367     // But the dialog user name input field can be left blank, in which
1368     // case we use the one configured in the object
1369     if (!adm_user.isEmpty()) cnf.user = adm_user;
1370     if (!dlg->m_dialog->uname->text().isEmpty())
1371         cnf.user = dlg->m_dialog->uname->text();
1372 
1373     cnf.pwd           = dlg->m_dialog->pwd->text();
1374     cnf.epwd          = dlg->m_dialog->epwd->text();
1375     cnf.quiet         = dlg->m_dialog->quiet->isChecked();
1376     cnf.verbose       = dlg->m_dialog->verbose->isChecked();
1377     cnf.stripComments = dlg->m_dialog->stripComments->isChecked();
1378     cnf.compressScript= dlg->m_dialog->compressScript->isChecked();
1379     cnf.copyFWB       = dlg->m_dialog->copyFWB->isChecked();
1380 
1381     dlg->savePassword();
1382     storeInstallerOptions();
1383 }
1384 
verifyManagementAddress()1385 bool instDialog::verifyManagementAddress()
1386 {
1387 /* check for a common error when none or multiple interfaces are marked as
1388  * 'management'
1389  */
1390     if (cnf.maddr.isEmpty() && cnf.putty_session.isEmpty() && cnf.fwobj)
1391     {
1392         int nmi = 0;
1393         list<FWObject*> ll = cnf.fwobj->getByTypeDeep(Interface::TYPENAME);
1394         for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++)
1395         {
1396             Interface *intf = Interface::cast( *i );
1397             if (intf->isManagement()) nmi++;
1398         }
1399 
1400         if (nmi>1)
1401         {
1402             QString err = QObject::tr("Only one interface of the firewall '%1' "
1403                                       "must be marked as management interface.\n")
1404                 .arg(QString::fromUtf8(cnf.fwobj->getName().c_str()));
1405 
1406             QMessageBox::critical(this, "Firewall Builder", err,
1407                                   tr("&Continue") );
1408             addToLog(err);
1409             return false;
1410         }
1411 
1412         if (nmi==0)
1413         {
1414             QString err = QObject::tr(
1415                 "One of the interfaces of the firewall '%1' "
1416                 "must be marked as management interface. "
1417                 "To set the management interface, double click "
1418                 "on the interface of the firewall that you will "
1419                 "connect to and check the box called Management "
1420                 "interface in the Editor panel")
1421                 .arg(QString::fromUtf8(cnf.fwobj->getName().c_str()));
1422 
1423             QMessageBox::critical(this, "Firewall Builder", err,
1424                                   tr("&Continue") );
1425             addToLog(err);
1426             return false;
1427         }
1428 
1429         if (cnf.maddr == "" ||
1430             cnf.maddr == QString(InetAddr::getAny().toString().c_str()))
1431         {
1432             QString err = QObject::tr(
1433                 "Management interface does not have IP address, "
1434                 "can not communicate with the firewall.\n");
1435 
1436             QMessageBox::critical(this, "Firewall Builder", err,
1437                                   tr("&Continue") );
1438             addToLog(err);
1439             return false;
1440         }
1441     }
1442     return true;
1443 }
1444 
logItemClicked(QUrl data)1445 void instDialog::logItemClicked(QUrl data)
1446 {
1447     QStringList parts = data.toString().split(':');
1448     if (parts[0] == "Error") return;
1449     if (parts.size()<3)
1450     {
1451         if(fwbdebug)
1452             cout << "Wrong error message clicked" << endl;
1453         return;
1454     }
1455     emit activateRule(project, parts[0], parts[1], parts[2].toInt());
1456 }
1457 
closeEvent(QCloseEvent *)1458 void instDialog::closeEvent(QCloseEvent *)
1459 {
1460     if (fwbdebug) qDebug() << "instDialog::closeEvent";
1461     if (proc.state() == QProcess::Running)
1462     {
1463         if (fwbdebug)
1464             qDebug() << "instDialog::closeEvent  killing process";
1465         proc.kill();
1466     }
1467     if (installer != NULL)
1468     {
1469         if (fwbdebug)
1470             qDebug() << "instDialog::closeEvent  killing installer";
1471         installer->terminate();
1472         delete installer;
1473         installer = NULL;
1474     }
1475 }
1476