1 /*
2 
3                           Firewall Builder
4 
5                  Copyright (C) 2005, 2006 NetCitadel, LLC
6 
7   Author:  Vadim Kurland     vadim@fwbuilder.org
8            Illiya Yalovoy    <yalovoy@gmail.com>
9 
10   $Id$
11 
12   This program is free software which we release under the GNU General Public
13   License. You may redistribute and/or modify this program under the terms
14   of that license as published by the Free Software Foundation; either
15   version 2 of the License, or (at your option) any later version.
16 
17   This program is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20   GNU General Public License for more details.
21 
22   To get a copy of the GNU General Public License, write to the Free Software
23   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 
25 */
26 
27 #include "config.h"
28 #include "global.h"
29 #include "utils.h"
30 #include "events.h"
31 
32 #include <qradiobutton.h>
33 #include <qlineedit.h>
34 #include <qcheckbox.h>
35 #include <qcombobox.h>
36 #include <qspinbox.h>
37 #include <qtimer.h>
38 #include <qregexp.h>
39 #include <qlabel.h>
40 #include <qtextbrowser.h>
41 #include <qtextedit.h>
42 #include <qpushbutton.h>
43 #include <qfile.h>
44 #include <qfiledialog.h>
45 #include <qapplication.h>
46 #include <qprogressdialog.h>
47 #include <qlistview.h>
48 #include <qtextstream.h>
49 #include <qiodevice.h>
50 #include <qhostaddress.h>
51 #include <qhostinfo.h>
52 #include <qgroupbox.h>
53 #include <qmessagebox.h>
54 #include <QtDebug>
55 
56 #include "DiscoveryDruid.h"
57 #include "ProjectPanel.h"
58 
59 #include "interfaceProperties.h"
60 #include "interfacePropertiesObjectFactory.h"
61 
62 #include <iostream>
63 #include <map>
64 #include <vector>
65 #include <set>
66 #include <memory>
67 
68 #include "fwbuilder/HostsFile.h"
69 #include "fwbuilder/IPv4.h"
70 #include "fwbuilder/IPv6.h"
71 #include "fwbuilder/Host.h"
72 #include "fwbuilder/Network.h"
73 #include "fwbuilder/NetworkIPv6.h"
74 #include "fwbuilder/InetAddr.h"
75 #include "fwbuilder/InetAddrMask.h"
76 #include "fwbuilder/Inet6AddrMask.h"
77 #include "fwbuilder/Firewall.h"
78 #include "fwbuilder/Policy.h"
79 
80 #include "fwbuilder/dns.h"
81 #include "fwbuilder/snmp.h"
82 #include "fwbuilder/Logger.h"
83 
84 #include "FWBSettings.h"
85 #include "ObjectManipulator.h"
86 #include "FWWindow.h"
87 #include "networkZoneManager.h"
88 
89 #include "IOSImporter.h"
90 #include "IPTImporter.h"
91 #include "PIXImporter.h"
92 
93 
94 using namespace std;
95 using namespace libfwbuilder;
96 
DiscoveryDruid(QWidget * parent,bool start_with_import)97 DiscoveryDruid::DiscoveryDruid(QWidget *parent, bool start_with_import) :
98     QDialog(parent)
99 {
100     init = true;
101 
102     discovered_fw = NULL;
103 
104     m_dialog = new Ui::DiscoveryDruid_q;
105     m_dialog->setupUi(this);
106 
107     setControlWidgets(this, m_dialog->stackedWidget,
108                       m_dialog->nextButton,
109                       m_dialog->finishButton,
110                       m_dialog->backButton,
111                       m_dialog->cancelButton,
112                       m_dialog->titleLabel);
113 
114     QTextCursor cursor(m_dialog->discoverylog->textCursor());
115     normal_format = cursor.charFormat();
116 
117     error_format = normal_format;
118     error_format.setForeground(QBrush(Qt::red));
119     error_format.setAnchorHref("http://somewhere.com");
120     error_format.setAnchor(true);
121     // weight must be between 0 and 99. Qt 4.4.1 does not seem to mind if
122     // it is >99 (just caps it) but older versions assert
123     error_format.setProperty(QTextFormat::FontWeight, 99);
124 
125     warning_format = normal_format;
126     warning_format.setForeground(QBrush(Qt::blue));
127     warning_format.setProperty(QTextFormat::FontWeight, 99);
128     warning_format.setAnchor(true);
129     warning_format.setAnchorHref("http://somewhere.com");
130 
131     dm_method = new QButtonGroup;
132     dm_method->addButton(m_dialog->dm_fromfile,0);
133     dm_method->addButton(m_dialog->dm_importdns,1);
134     dm_method->addButton(m_dialog->dm_usesnmp,2);
135     dm_method->addButton(m_dialog->dm_import_config,3);
136 
137     connect(dm_method, SIGNAL( buttonClicked(int) ),
138             this, SLOT( changedDiscoveryMethod(int) ) );
139     connect(m_dialog->dnsfromlist, SIGNAL( clicked(bool) ),
140             this, SLOT( changedNameServer() ) );
141     connect(m_dialog->dnscustom, SIGNAL( clicked(bool) ),
142             this, SLOT( changedNameServer() ) );
143     connect(m_dialog->nameserverlist, SIGNAL( editTextChanged(QString) ),
144             this, SLOT( changedNameServer() ) );
145     connect(m_dialog->nameserverline, SIGNAL( textChanged(QString) ),
146             this, SLOT( changedNameServer() ) );
147 
148     thread = NULL;
149 
150     timer = new QTimer(this);
151     prg_timer = new QTimer(this);
152     unBar = NULL;
153     unProg = 0;
154 
155     connect(prg_timer,SIGNAL(timeout()),this,SLOT(updatePrg()));
156 
157     setDiscoveryMethod_file();
158 
159     flt_obj     = new Filter();
160     flt_obj_d   = new FilterDialog(this);
161     flt_obj_d->setFilter(flt_obj);
162 
163     flt_last    = new Filter();
164     flt_last_d  = new FilterDialog(this);
165     flt_last_d->setFilter(flt_last);
166 
167     flt_net     = new Filter();
168     flt_net_d   = new FilterDialog(this);
169     flt_net_d->setFilter(flt_net);
170 
171     assert(mw->activeProject()->db());
172 
173     fillLibraries(m_dialog->libs, mw->activeProject()->db());
174     m_dialog->libs->setEditable(true);
175     m_dialog->libs->lineEdit()->setText(mw->getCurrentLib()->getName().c_str());
176 
177     m_dialog->DNSprogress->hide();
178     m_dialog->DNSprogress_2->hide();
179 
180 #ifndef HAVE_GOODLIBRESOLV
181     m_dialog->dm_importdns->hide();
182     m_dialog->snmpdnsparameters->hide();
183 #endif
184 
185 #ifndef HAVE_LIBSNMP
186     m_dialog->dm_usesnmp->setEnabled(false);
187 #endif
188 
189     restore();
190 
191     importPlatformChanged(m_dialog->import_platform->currentIndex());
192 
193     showPage(CHOOSE_METHOD_PAGE);
194     setNextEnabled(CHOOSE_METHOD_PAGE, true);
195 
196     if (start_with_import)
197     {
198         m_dialog->dm_import_config->setDown(true);
199         setDiscoveryMethod_Import();
200         setAppropriate( CHOOSE_METHOD_PAGE, false );
201         // show the first page of the "import policy" track of the wizard
202         showPage( IMPORT_CONFIG_PAGE );
203         setNextEnabled(IMPORT_CONFIG_PAGE, false);
204         cancelButton->show();
205     }
206 
207     prg_timer->start(100);
208 
209     init = false;
210 }
211 
nextClicked()212 void DiscoveryDruid::nextClicked()
213 {
214     if (nextRelevant( currentPage() ) > -1)
215         showPage(nextRelevant( currentPage() ));
216 }
217 
backClicked()218 void DiscoveryDruid::backClicked()
219 {
220     if (previousRelevant( currentPage() ) > -1)
221         showPage(previousRelevant( currentPage() ));
222 }
223 
finishClicked()224 void DiscoveryDruid::finishClicked()
225 {
226     if (current_task == BT_IMPORT && discovered_fw != NULL)
227     {
228         if (selectedPlatform() == "pix" && currentPage() == NETWORK_ZONES_PAGE)
229         {
230             // read and configure network zones
231             list<FWObject*> all_interfaces =
232                 discovered_fw->getByTypeDeep(Interface::TYPENAME);
233             list<FWObject*>::iterator it;
234             for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it)
235             {
236                 Interface *iface = Interface::cast(*it);
237 
238                 string  network_zone_str_id = "";
239 
240                 QList<QTableWidgetItem*> ltwi =
241                     m_dialog->iface_nz_list->findItems( iface->getName().c_str(),
242                                                         Qt::MatchExactly );
243                 if ( ! ltwi.empty())
244                 {
245                     QTableWidgetItem *itm2 = ltwi[0];
246                     assert(itm2!=NULL);
247                     int row = itm2->row();
248                     QComboBox *cb = dynamic_cast<QComboBox*>(
249                         m_dialog->iface_nz_list->cellWidget(row, 3));
250                     assert(cb!=NULL);
251                     int network_zone_int_id =
252                         cb->itemData(cb->currentIndex(), Qt::UserRole).toInt();
253                     if (network_zone_int_id != 0)
254                         network_zone_str_id = FWObjectDatabase::getStringId(
255                             network_zone_int_id);
256                     else
257                         network_zone_str_id = "";
258                 }
259 
260                 // only set network zone if it is supported and is not
261                 // empty. See #2014
262                 if (!network_zone_str_id.empty())
263                     iface->setStr("network_zone", network_zone_str_id);
264 
265             }
266         }
267 
268         QCoreApplication::postEvent(
269             mw->activeProject(), new expandObjectInTreeEvent(
270                 mw->activeProject()->getFileName(), discovered_fw->getId()));
271 
272         QCoreApplication::postEvent(
273             mw->activeProject(), new showObjectInTreeEvent(
274                 mw->activeProject()->getFileName(), discovered_fw->getId()));
275 
276         QCoreApplication::postEvent(
277             mw, new openObjectInEditorEvent(
278                 mw->activeProject()->getFileName(), discovered_fw->getId()));
279 
280     }
281 
282     QDialog::accept();
283 }
284 
cancelClicked()285 void DiscoveryDruid::cancelClicked()
286 {
287     QDialog::reject();
288 }
289 
~DiscoveryDruid()290 DiscoveryDruid::~DiscoveryDruid()
291 {
292     save();
293 
294     delete flt_obj;
295     delete flt_last;
296     delete flt_net;
297     delete flt_obj_d;
298     delete flt_last_d;
299     delete flt_net_d;
300 
301     delete m_dialog;
302     delete dm_method;
303 }
304 
305 const char * DISCOVERY_DRUID_PREFIX="DiscoveryDruid/";
306 
307 const char * DISCOVERY_DRUID_DISCOVERYMETHOD="DiscoveryMethod";
308 const char * DISCOVERY_DRUID_FILENAME       ="Filename";
309 const char * DISCOVERY_DRUID_DOMAINNAME     ="Domainname";
310 const char * DISCOVERY_DRUID_USELONGNAME    ="UseLongName";
311 const char * DISCOVERY_DRUID_NAMESERVER     ="NameServer";
312 const char * DISCOVERY_DRUID_DNSTIMEOUT     ="DNSTimeout";
313 const char * DISCOVERY_DRUID_DNSRETRIES     ="DNSRetries";
314 const char * DISCOVERY_DRUID_SEEDHOST       ="SeedHost";
315 const char * DISCOVERY_DRUID_SNMPINADDR     ="SNMPInAddr";
316 const char * DISCOVERY_DRUID_SNMPINMASK     ="SNMPInMask";
317 const char * DISCOVERY_DRUID_SNMPRECURSIVE  ="SNMPRecursive";
318 const char * DISCOVERY_DRUID_SNMPFOLLOWP2P  ="SNMPFollowP2P";
319 const char * DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED="SnmpIncludeUnnumbered";
320 const char * DISCOVERY_DRUID_SNMPDODNS      ="SNMPDoDNS";
321 const char * DISCOVERY_DRUID_SNMPCOMMUNITY  ="SNMPCommunity";
322 const char * DISCOVERY_DRUID_SNMPRETRIES    ="SNMPRetries";
323 const char * DISCOVERY_DRUID_SNMPTIMEOUT    ="SNMPTimeout";
324 const char * DISCOVERY_DRUID_SNMPDNSRETRIES ="DNSRetries";
325 const char * DISCOVERY_DRUID_SNMPDNSTIMEOUT ="DNSTimeout";
326 const char * DISCOVERY_DRUID_SNMPDNSTHREADS ="SNMPDnsThreads";
327 const char * DISCOVERY_DRUID_IMPORRT_CONFIG_PLATFORM = "ImportPlatform";
328 
329 
restore()330 void DiscoveryDruid::restore()
331 {
332     int i;
333     QString s;
334     //Restore from settings
335     dm_method->button(st->getInt(
336                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DISCOVERYMETHOD))->setChecked(true);
337     changedDiscoveryMethod(dm_method->checkedId());
338 
339     //m_dialog->filename->setText(st->getStr(
340     //            QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_FILENAME));
341     //m_dialog->domainname->setText(st->getStr(
342     //            QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DOMAINNAME));
343     m_dialog->uselongname->setChecked(st->getBool(
344                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_USELONGNAME));
345     //m_dialog->nameserverline->setText(st->getStr(
346     //            QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_NAMESERVER));
347     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSTIMEOUT);
348     m_dialog->dnstimeout->setValue((i)?i:2);
349     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSRETRIES);
350     m_dialog->dnsretries->setValue((i)?i:1);
351 
352     m_dialog->seedhostname->setText(st->getStr(
353                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SEEDHOST));
354     m_dialog->snmpinaddr->setText(st->getStr(
355                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINADDR));
356     m_dialog->snmpinmask->setText(st->getStr(
357                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINMASK));
358     m_dialog->snmprecursive->setChecked(st->getBool(
359                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRECURSIVE));
360     m_dialog->snmpfollowp2p->setChecked(st->getBool(
361                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPFOLLOWP2P));
362     m_dialog->snmpincludeunnumbered->setChecked(st->getBool(
363                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED));
364     m_dialog->snmpdodns->setChecked(st->getBool(
365                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDODNS));
366     s=st->getStr(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPCOMMUNITY);
367     m_dialog->snmpcommunity->setText((s.isEmpty())?"public":s);
368     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRETRIES);
369     m_dialog->snmpretries->setValue((i)?i:1);
370     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPTIMEOUT);
371     m_dialog->snmptimeout->setValue((i)?i:2);
372     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSRETRIES);
373     m_dialog->snmpdnsretries->setValue((i)?i:1);
374     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTIMEOUT);
375     m_dialog->snmpdnstimeout->setValue((i)?i:2);
376     i=st->getInt(QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTHREADS);
377     m_dialog->snmpdnsthreads->setValue((i)?i:5);
378 
379     m_dialog->import_platform->setCurrentIndex(st->getInt(
380            QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_IMPORRT_CONFIG_PLATFORM));
381 }
382 
save()383 void DiscoveryDruid::save()
384 {
385     // Save to settings
386     st->setInt(
387             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DISCOVERYMETHOD,
388             dm_method->checkedId());
389     st->setBool(
390             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_USELONGNAME,
391             m_dialog->uselongname->isChecked());
392     if (current_task==BT_DNS)
393     {
394         st->setInt(
395                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSTIMEOUT,
396                 m_dialog->dnstimeout->value());
397         st->setInt(
398                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_DNSRETRIES,
399                 m_dialog->dnsretries->value());
400     }
401     else
402     {
403         st->setInt(
404                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSRETRIES,
405                 m_dialog->snmpdnsretries->value());
406         st->setInt(
407                 QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTIMEOUT,
408                 m_dialog->snmpdnstimeout->value());
409     }
410     st->setStr(
411             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SEEDHOST,
412             m_dialog->seedhostname->text());
413     st->setStr(
414             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINADDR,
415             m_dialog->snmpinaddr->text());
416     st->setStr(
417             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINMASK,
418             m_dialog->snmpinmask->text());
419     st->setBool(
420             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRECURSIVE,
421             m_dialog->snmprecursive->isChecked());
422     st->setBool(
423             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPFOLLOWP2P,
424             m_dialog->snmpfollowp2p->isChecked());
425     st->setBool(
426             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPINCLUDEUNNUMBERED,
427             m_dialog->snmpincludeunnumbered->isChecked());
428     st->setBool(
429             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDODNS,
430             m_dialog->snmpdodns->isChecked());
431     st->setStr(
432             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPCOMMUNITY,
433             m_dialog->snmpcommunity->text());
434     st->setInt(
435             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPRETRIES,
436             m_dialog->snmpretries->value());
437     st->setInt(
438             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPTIMEOUT,
439             m_dialog->snmptimeout->value());
440     st->setInt(
441             QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_SNMPDNSTHREADS,
442             m_dialog->snmpdnsthreads->value());
443     st->setInt(
444         QString(DISCOVERY_DRUID_PREFIX) + DISCOVERY_DRUID_IMPORRT_CONFIG_PLATFORM,
445         m_dialog->import_platform->currentIndex());
446 
447 }
448 
dnsFinish(QHostInfo host)449 void DiscoveryDruid::dnsFinish(QHostInfo host)
450 {
451     QList<QHostAddress> list = host.addresses();
452 
453     unBar->hide();
454 
455     if (userIsTyping)
456     {
457         //abandon the test result
458         if (current_task==BT_DNS)
459         {
460             changedNameServer();
461         }
462         else
463         {
464             changedSeedHost();
465         }
466     }
467     else
468     {
469         //get the test result
470         if (list.isEmpty())
471         {
472             QPalette palette = errMessage->palette();
473             palette.setColor(errMessage->foregroundRole(), Qt::darkRed);
474             errMessage->setPalette(palette);
475 
476             errMessage->setText( "host name not found");
477             isSeedHostOK=false;
478         }
479         else
480         {
481             QPalette palette = errMessage->palette();
482             palette.setColor(errMessage->foregroundRole(), Qt::darkGreen);
483             errMessage->setPalette(palette);
484 
485             errMessage->setText( "host name verified");
486             isSeedHostOK=true;
487 
488         }
489         nextButton->setEnabled(isSNMPInclNetOK && isSeedHostOK);
490     }
491 
492 }
493 
changedSelected(const int & page)494 void DiscoveryDruid::changedSelected( const int &page )
495 {
496     if (init) return;
497 
498     switch (page)
499     {
500 
501     case READ_HOSTS_FILE_PAGE: // Reading file in hosts format
502     {
503         setNextEnabled(page, false);
504         changedHostsFileName();
505         m_dialog->filename->setFocus();
506         break;
507     }
508 
509     case IMPORT_CONFIG_PAGE: // import config
510     {
511         m_dialog->obj_name->setFocus();
512         setBackEnabled(page, true);
513         setFinishEnabled(page, false);
514         break;
515     }
516 
517     case IMPORT_DNS_ZONE_PAGE: // Import DNS zone
518     {
519         changedDomainName();
520         m_dialog->domainname->setFocus();
521         //setNextEnabled(page,false);
522         break;
523     }
524 
525     case NAME_SERVER_PAGE: // Name server
526     {
527         if (page>FromPage)
528             getNameServers();
529         disconnect(timer,SIGNAL(timeout()),0,0);
530         connect(timer,SIGNAL(timeout()),this,SLOT(checkHostName()));
531         changedNameServer();
532         m_dialog->nameserverline->setFocus();
533 
534         //setNextEnabled(page,false);
535         break;
536     }
537 
538     case SNMP_DISCOVERY_PAGE: // Network discovery using SNMP
539     {
540         disconnect(timer,SIGNAL(timeout()),0,0);
541         connect(timer,SIGNAL(timeout()),this,SLOT(checkHostName()));
542 
543         isSeedHostOK=false;
544         isSNMPInclNetOK=false;
545 
546         changedSeedHost();
547         changedInclNet();
548         m_dialog->seedhostname->setFocus();
549         break;
550     }
551 
552     case NETWORK_SCAN_OPTIONS_PAGE: // Network scan options
553     {
554         m_dialog->snmprecursive->setFocus();
555         //setNextEnabled(page,false);
556         break;
557     }
558 
559     case SNMP_PARAMETERS_PAGE: // SNMP and DNS reverse lookup queries parameters
560     {
561         checkSNMPCommunity();
562         m_dialog->snmpcommunity->setFocus();
563         break;
564     }
565 
566     case BACKGROUND_PROCESS_PAGE: // Background process (import from hosts and from config file)
567     {
568         m_dialog->discoveryprogress->setValue(-1);
569         m_dialog->discoverylog->clear();
570         m_dialog->discoveryStopButton->setEnabled(true);
571         m_dialog->logSaveButton->setEnabled(false);
572 
573         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents,100);
574 
575         setNextEnabled(page, false);
576         cancelButton->hide();
577         setBackEnabled(page, false);
578         disconnect(timer, SIGNAL(timeout()), 0, 0);
579         connect(timer, SIGNAL(timeout()), this, SLOT(updateLog()));
580         timer->setSingleShot(false);
581         timer->start(1000);
582 
583         startBackgroundProcess();
584         break;
585     }
586 
587     case CHOOSE_NETWORKS_PAGE: // Networks
588     {
589         fillListOfNetworks();
590         fillNetworks();
591         backButton->setEnabled(false);
592         nextButton->setEnabled(m_dialog->networklist->count ()>0 || Objects.size()>0);
593         break;
594     }
595 
596     case CHOOSE_OBJECTS_PAGE: // Objects
597     {
598         if (Networks.size()==0)
599             setBackEnabled(page,false);
600 
601         fillListOfObjects();
602         fillObjects();
603         nextButton->setEnabled(m_dialog->objectlist->count ()>0 || m_dialog->networklist->count()>0);
604         break;
605     }
606 
607     case ADJUST_OBJECT_TYPES_PAGE: // Adjust Object type
608     {
609         setBackEnabled(page,true);
610         fillTypeChangingList();
611         break;
612     }
613 
614     case TARGET_LIB_PAGE: // Target library
615     {
616         break;
617     }
618 
619     case CREATE_OBJECTS_PAGE: // Objects creation ...
620     {
621         setBackEnabled(page,false);
622         cancelButton->hide();
623         createRealObjects();
624         setNextEnabled(page, false);
625         setFinishEnabled(page, true);
626         finishButton->setFocus();
627         break;
628     }
629 
630     case NETWORK_ZONES_PAGE: // Network zones for PIX
631     {
632         setBackEnabled(page, false);
633         cancelButton->hide();
634         setNextEnabled(page, false);
635         setFinishEnabled(page, true);
636         finishButton->setFocus();
637         fillNetworkZones();
638         break;
639     }
640 
641     default : {}
642 
643     }
644     FromPage = page;
645 }
646 
startBackgroundProcess()647 void DiscoveryDruid::startBackgroundProcess()
648 {
649     switch (current_task)
650     {
651         case BT_HOSTS:
652         case BT_IMPORT:
653         {
654             m_dialog->discoveryprogress->setMaximum(100);
655             m_dialog->discoveryprogress->setValue(0);
656             m_dialog->discoveryprogress->setEnabled(false);
657             m_dialog->discoveryStopButton->setEnabled(false);
658             break;
659         }
660         case BT_DNS:
661         case BT_SNMP:
662         {
663             m_dialog->discoveryprogress->setMaximum(0);
664             m_dialog->discoveryprogress->setValue(-1);
665             break;
666         }
667         default:
668         {}
669     }
670 
671     switch (current_task)
672     {
673         case BT_HOSTS:    startHostsScan();     break;
674         case BT_DNS:      startDNSScan();       break;
675         case BT_SNMP:     startSNMPScan();      break;
676         case BT_IMPORT:   startConfigImport();  break;
677         default:
678         {}
679     }
680 
681 }
682 
browseHostsFile()683 void DiscoveryDruid::browseHostsFile()
684 {
685     QString s = QFileDialog::getOpenFileName(
686                     this,
687                     "Choose a file",
688                     st->getOpenFileDir(),
689                     "All files (*)");
690 
691     if (s.isEmpty()) return;
692     st->setOpenFileDir(s);
693 
694     m_dialog->filename->setText(s);
695 
696 }
697 
browseForImport()698 void DiscoveryDruid::browseForImport()
699 {
700     QString s = QFileDialog::getOpenFileName(
701                     this,
702                     "Choose a file",
703                     st->getOpenFileDir(),
704                     "All files (*)");
705 
706     if (s.isEmpty()) return;
707     st->setOpenFileDir(s);
708 
709     m_dialog->import_filename->setText(s);
710 }
711 
updatePrg()712 void DiscoveryDruid::updatePrg()
713 {
714     if (unBar!=NULL)
715     {
716         unBar->setValue(unProg++);
717     }
718 }
719 
getNameServers()720 void DiscoveryDruid::getNameServers()
721 {
722     // this is not supported anymore since all resolver functions
723     // have been removed from class DNS
724     m_dialog->nameserverlist->setEnabled(false);
725     m_dialog->dnsfromlist->setEnabled(false);
726     m_dialog->dnscustom->setChecked(true);
727 }
728 
setDiscoveryMethod_file()729 void DiscoveryDruid::setDiscoveryMethod_file()
730 {
731     m_dialog->processname->setText(tr("Hosts file parsing ..."));
732     current_task = BT_HOSTS;
733     for (int i=0; i<WIZARD_PAGES; i++)
734     {
735         setAppropriate( i, WIZARD_FILE_PAGES[i]);
736     }
737 }
738 
setDiscoveryMethod_DNS()739 void DiscoveryDruid::setDiscoveryMethod_DNS()
740 {
741     m_dialog->processname->setText(tr("DNS zone transfer ..."));
742     current_task = BT_DNS;
743     for (int i=0; i<WIZARD_PAGES; i++)
744     {
745         setAppropriate( i, WIZARD_DNS_PAGES[i]);
746     }
747 }
748 
setDiscoveryMethod_SNMP()749 void DiscoveryDruid::setDiscoveryMethod_SNMP()
750 {
751     m_dialog->processname->setText(tr("Network discovery using SNMP ..."));
752     current_task = BT_SNMP;
753     for (int i=0; i<WIZARD_PAGES; i++)
754     {
755         setAppropriate( i, WIZARD_SNMP_PAGES[i]);
756     }
757 }
758 
setDiscoveryMethod_Import()759 void DiscoveryDruid::setDiscoveryMethod_Import()
760 {
761     m_dialog->processname->setText(tr("Import configuration from file ..."));
762     current_task = BT_IMPORT;
763     for (int i=0; i<WIZARD_PAGES; i++)
764     {
765         setAppropriate( i, WIZARD_IMPORT_PAGES[i]);
766     }
767 }
768 
769 
changedDiscoveryMethod(int c)770 void DiscoveryDruid::changedDiscoveryMethod(int c)
771 {
772     if (fwbdebug)
773         qDebug("DiscoveryDruid::changedDiscoveryMethod c=%d",c);
774 
775     switch (c)
776     {
777     case 0:
778     {
779         setDiscoveryMethod_file();
780         break;
781     }
782     case 1:
783     {
784         setDiscoveryMethod_DNS();
785         break;
786     }
787     case 2:
788     {
789         setDiscoveryMethod_SNMP();
790         break;
791     }
792     case 3:
793     {
794         setDiscoveryMethod_Import();
795         break;
796     }
797 
798        default : {}
799    }
800 }
801 
startHostsScan()802 void DiscoveryDruid::startHostsScan()
803 {
804     if (thread!=NULL)
805     {
806         delete thread;
807     }
808 
809     thread = new HostsFileImport(m_dialog->filename->text());
810     thread->setTargetWidget(this);
811     thread->start();
812 }
813 
startConfigImport()814 void DiscoveryDruid::startConfigImport()
815 {
816     if (thread!=NULL)
817     {
818         delete thread;
819     }
820 
821     QFile cf( m_dialog->import_filename->text()  );
822     if (cf.open( QIODevice::ReadOnly ) )
823     {
824         QTextStream stream(&cf);
825         QString s = stream.readAll();
826         cf.close();
827         std::string *buffer = new std::string( s.toLatin1().constData() );
828         //if (fwbdebug) qDebug(buffer->c_str());
829 
830         // count lines, gather some general stats on the config file.
831 
832         std::string::size_type pos, n;
833         pos = 0;
834         int line_count = 0;
835         while ( (n=buffer->find('\n', pos))!=std::string::npos)
836         {
837             line_count++;
838             pos = n+1;
839         }
840         m_dialog->discoveryprogress->setMaximum(line_count);
841 
842         // need to pick right platform string based on
843         // m_dialog->import_platform->currentItem()
844         string platform = selectedPlatform();
845 
846         //
847         // ConfigImport "owns" buffer - it is deleted
848         // in destructor of ConfigImport
849         //
850         thread = new ConfigImport(buffer, platform, m_dialog->obj_name->text().toStdString());
851         thread->setTargetWidget(this);
852         thread->start();
853 
854     } else
855     {
856         QMessageBox::critical(this, tr("Discovery error"),
857           tr("Could not open file %1").arg(m_dialog->import_filename->text()));
858         setBackEnabled(currentPage(),true);
859     }
860 }
861 
selectedPlatform()862 string DiscoveryDruid::selectedPlatform()
863 {
864     string platform = "";
865     switch (m_dialog->import_platform->currentIndex())
866     {
867     case IMPORT_IOS: platform = "iosacl"; break;
868     case IMPORT_IPT: platform = "iptables"; break;
869     case IMPORT_PIX: platform = "pix"; break;
870     }
871     return platform;
872 }
873 
getNS()874 InetAddr DiscoveryDruid::getNS()
875 {
876     string ns;
877     if (m_dialog->dnscustom->isChecked())
878     {
879         ns=m_dialog->nameserverline->text().toLatin1().constData();
880 
881         try
882         {
883             return InetAddr(ns);
884         } catch (FWException &ex)
885         {
886         /* perhaps not address but host name */
887             list<InetAddr> addr;
888             try
889             {
890                 addr=DNS::getHostByName(ns);
891             } catch (FWException &ex)
892             {
893                 return InetAddr();
894             }
895 
896             return addr.front();
897         }
898     }
899 
900     return NameServers[m_dialog->nameserverlist->currentText()];
901 }
902 
startDNSScan()903 void DiscoveryDruid::startDNSScan()
904 {
905     // this is not supported since all resolver functions have been
906     // removed from class DNS
907 }
908 
getSeedHostAddress()909 InetAddr DiscoveryDruid::getSeedHostAddress()
910 {
911     if (fwbdebug)
912         qDebug() <<
913             QString("DiscoveryDruid::getSeedHostAddress(): Seed host name %1").
914             arg(m_dialog->seedhostname->text());
915 
916     libfwbuilder::InetAddr   seed_host_addr;
917     if (!m_dialog->seedhostname->text().isEmpty())
918     {
919         try
920         {
921             QString a = getAddrByName( m_dialog->seedhostname->text(), AF_INET);
922             if (fwbdebug)
923                 qDebug() <<
924                     QString("DiscoveryDruid::getSeedHostAddress() address: %1").
925                     arg(a);
926 
927             return InetAddr( a.toLatin1().constData() );
928         } catch(const FWException &ex)
929         {
930         }
931 
932         try
933         {
934             seed_host_addr = InetAddr(
935                 m_dialog->seedhostname->text().toLatin1().constData());
936             return seed_host_addr;
937         } catch(const FWException &ex)
938         {
939         }
940 
941     }
942     return seed_host_addr;
943 }
944 
changedDomainName()945 void DiscoveryDruid::changedDomainName()
946 {
947     if (m_dialog->domainname->text().isEmpty())
948     {
949         nextButton->setEnabled(false);
950     }
951     else
952     {
953         nextButton->setEnabled(true);
954     }
955 }
956 
changedNameServer()957 void DiscoveryDruid::changedNameServer()
958 {
959     userIsTyping=true;
960     isSNMPInclNetOK=true;
961 
962     if(m_dialog->dnscustom->isChecked())
963     {
964         nextButton->setEnabled(false);
965         QString s=m_dialog->nameserverline->text();
966         HostName=s;
967 
968         if (s.isEmpty())
969         {
970             timer->stop();
971             m_dialog->DNSprogress_2->hide();
972 
973             QPalette palette = m_dialog->nameserver_error->palette();
974             palette.setColor(m_dialog->nameserver_error->foregroundRole(), Qt::darkRed);
975             m_dialog->nameserver_error->setPalette(palette);
976 
977             m_dialog->nameserver_error->setText("Enter valid host name or address.");
978             nextButton->setEnabled(false);
979             return;
980         }
981 
982         if(isInetAddr(s))
983         {
984             timer->stop();
985             m_dialog->DNSprogress_2->hide();
986 
987             QString rs=testInetAddr(s);
988             if (rs.isEmpty())
989             {
990                 m_dialog->nameserver_error->setText(" ");
991                 nextButton->setEnabled(true);
992             }
993             else
994             {
995                 QPalette palette = m_dialog->nameserver_error->palette();
996                 palette.setColor(m_dialog->nameserver_error->foregroundRole(), Qt::darkRed);
997                 m_dialog->nameserver_error->setPalette(palette);
998 
999                 m_dialog->nameserver_error->setText(rs);
1000                 nextButton->setEnabled(false);
1001             }
1002         }
1003         else
1004         {
1005             unBar=m_dialog->DNSprogress_2;
1006 
1007             unBar->show();
1008             timer->setSingleShot(true);
1009             timer->start(1000);
1010             errMessage=m_dialog->nameserver_error;
1011             userIsTyping=false;
1012 
1013             QPalette palette = errMessage->palette();
1014             palette.setColor(errMessage->foregroundRole(), Qt::black);
1015             errMessage->setPalette(palette);
1016 
1017             errMessage->setText("DNS resolution in progress...");
1018 
1019             unProg = 0;
1020         }
1021     }
1022     else
1023     {
1024         timer->stop();
1025         m_dialog->DNSprogress_2->hide();
1026         m_dialog->nameserver_error->setText(" ");
1027         nextButton->setEnabled(true);
1028     }
1029 }
1030 
typedCustomNS()1031 void DiscoveryDruid::typedCustomNS()
1032 {
1033     if(!m_dialog->dnscustom->isChecked())
1034     {
1035         m_dialog->dnscustom->setChecked(true);
1036     }
1037 }
1038 
isInetAddr(const QString s)1039 bool DiscoveryDruid::isInetAddr(const QString s)
1040 {
1041     QRegExp r=QRegExp("^(\\d|\\.)+$",Qt::CaseInsensitive); //non wildcard
1042     return r.exactMatch(s);
1043 }
1044 
testInetAddr(const QString s)1045 QString DiscoveryDruid::testInetAddr(const QString s)
1046 {
1047     QString res;
1048     QRegExp r=QRegExp("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$",Qt::CaseInsensitive); //non wildcard
1049     if (r.exactMatch(s))
1050     {
1051         try
1052         {
1053             InetAddr(s.toLatin1().constData());
1054         } catch(const FWException &ex)
1055         {
1056             res=ex.toString().c_str();
1057         }
1058     }
1059     else
1060     {
1061         res="Wrong IPv4 format";
1062     }
1063     return res;
1064 }
1065 
changedHostsFileName()1066 void DiscoveryDruid::changedHostsFileName()
1067 {
1068     QFile f;
1069     f.setFileName(m_dialog->filename->text());
1070     if (f.exists())
1071     {
1072         setNextEnabled(currentPage(),true);
1073     }
1074     else
1075     {
1076         setNextEnabled(currentPage(),false);
1077     }
1078 }
1079 
changedSNMPOptions()1080 void DiscoveryDruid::changedSNMPOptions()
1081 {
1082 
1083 }
1084 
stopBackgroundProcess()1085 void DiscoveryDruid::stopBackgroundProcess()
1086 {
1087     if (fwbdebug)
1088         qDebug("stopBackgroundProcess bop=%p  isRunning=%d",
1089                bop,(bop!=NULL)?bop->isRunning():-1);
1090 
1091     if (bop!=NULL && bop->isRunning())
1092     {
1093         addToLog("Terminating task. Please wait...");
1094 
1095         bop->stop_operation();
1096         m_dialog->discoveryStopButton->setEnabled(false);
1097     }
1098 }
1099 
addNetwork()1100 void DiscoveryDruid::addNetwork()
1101 {
1102 
1103 
1104     int count = m_dialog->networkresultlist->count();
1105     int upd_max=(count > 10)?count/10:1;
1106     int updc=upd_max;
1107     int t=0;
1108     QProgressDialog pd(tr("Adding objects ..."), tr("Cancel"), 0, count,this);
1109 
1110     QListWidgetItem* item=(QListWidgetItem*)m_dialog->networkresultlist->item(0);
1111     int i = 0;
1112 
1113     while (item)
1114     {
1115 
1116         if (item->isSelected())
1117         {
1118             QString k=item->text();
1119             if (!Networks[k].isSelected)
1120             {
1121                 Networks[k].isSelected=true;
1122                 m_dialog->networklist->addItem(item->text());
1123             }
1124         }
1125 
1126         i++;
1127         item=(QListWidgetItem*)m_dialog->networkresultlist->item(i);
1128 
1129         if (updc--<=0)
1130         {
1131             pd.setValue(t);
1132             qApp->processEvents();
1133 
1134             if (pd.wasCanceled())
1135             {
1136                 break;
1137             }
1138             updc=upd_max;
1139         }
1140         t++;
1141     }
1142     nextButton->setEnabled(m_dialog->networklist->count ()>0 || Objects.size()>0);
1143 
1144 }
1145 
removeNetwork()1146 void DiscoveryDruid::removeNetwork()
1147 {
1148     QListWidgetItem* item1=m_dialog->networklist->item(0);
1149     QListWidgetItem* item2;
1150 
1151     while (item1!=0)
1152     {
1153         item2=m_dialog->networklist->item(
1154                 m_dialog->networklist->row(item1)+1);
1155         if (item1->isSelected())
1156         {
1157             Networks[item1->text()].isSelected=false;
1158             delete item1;
1159         }
1160         item1=item2;
1161     }
1162     nextButton->setEnabled(m_dialog->networklist->count ()>0 || Objects.size()>0);
1163 }
1164 
setNetworkFilter()1165 void DiscoveryDruid::setNetworkFilter()
1166 {
1167     flt_net_d->exec();
1168     fillListOfNetworks();
1169 }
1170 
removeNetworkFilter()1171 void DiscoveryDruid::removeNetworkFilter()
1172 {
1173     flt_net->clear();
1174     fillListOfNetworks();
1175 }
1176 
addObject()1177 void DiscoveryDruid::addObject()
1178 {
1179     int count = m_dialog->objectresultlist->count();
1180     int upd_max=(count > 10)?count/10:1;
1181     int updc=upd_max;
1182     int t=0;
1183     QProgressDialog pd(tr("Adding objects ..."),
1184                        tr("Cancel"), 0, count,this);
1185 
1186     QListWidgetItem* item=(QListWidgetItem*)m_dialog->objectresultlist->item(0);
1187     int i = 0;
1188 
1189     while (item)
1190     {
1191         if (item->isSelected())
1192         {
1193             QString k=item->text();
1194             if (!Objects[k].isSelected)
1195             {
1196                 Objects[k].isSelected=true;
1197                 m_dialog->objectlist->addItem(item->text());
1198             }
1199         }
1200 
1201         i++;
1202         item=(QListWidgetItem*)m_dialog->objectresultlist->item(i);
1203 
1204         if (updc--<=0)
1205         {
1206             pd.setValue(t);
1207             qApp->processEvents();
1208 
1209             if (pd.wasCanceled())
1210             {
1211                 break;
1212             }
1213             updc=upd_max;
1214         }
1215         t++;
1216     }
1217     nextButton->setEnabled(m_dialog->objectlist->count ()>0 || m_dialog->networklist->count()>0);
1218 }
1219 
removeObject()1220 void DiscoveryDruid::removeObject()
1221 {
1222     QListWidgetItem* item1=m_dialog->objectlist->item(0);
1223     QListWidgetItem* item2;
1224 
1225     while (item1!=0)
1226     {
1227         item2=m_dialog->objectlist->item(
1228                 m_dialog->objectlist->row(item1)+1);
1229         if (item1->isSelected())
1230         {
1231             Objects[item1->text()].isSelected=false;
1232             delete item1;
1233         }
1234         item1=item2;
1235     }
1236     nextButton->setEnabled(m_dialog->objectlist->count ()>0 || m_dialog->networklist->count()>0);
1237 }
1238 
setLastFilter()1239 void DiscoveryDruid::setLastFilter()
1240 {
1241     flt_last_d->exec();
1242     fillTypeChangingList();
1243 }
1244 
setObjectFilter()1245 void DiscoveryDruid::setObjectFilter()
1246 {
1247     flt_obj_d->exec();
1248     fillListOfObjects();
1249 }
1250 
removeLastFilter()1251 void DiscoveryDruid::removeLastFilter()
1252 {
1253     flt_last->clear();
1254     fillTypeChangingList();
1255 }
1256 
removeObjectFilter()1257 void DiscoveryDruid::removeObjectFilter()
1258 {
1259     flt_obj->clear();
1260     fillListOfObjects();
1261 }
1262 
selectAllResNets()1263 void DiscoveryDruid::selectAllResNets()
1264 {
1265     m_dialog->networkresultlist->selectAll();
1266 }
1267 
selectAllNets()1268 void DiscoveryDruid::selectAllNets()
1269 {
1270     m_dialog->networklist->selectAll();
1271 }
1272 
selectAllResObjs()1273 void DiscoveryDruid::selectAllResObjs()
1274 {
1275     m_dialog->objectresultlist->selectAll();
1276 }
1277 
selectAllObjs()1278 void DiscoveryDruid::selectAllObjs()
1279 {
1280     m_dialog->objectlist->selectAll();
1281 }
1282 
fillNetworkZones()1283 void DiscoveryDruid::fillNetworkZones()
1284 {
1285     m_dialog->iface_nz_list->clear();
1286 
1287     QStringList labels;
1288     labels << QObject::tr("Name") << QObject::tr("Label")
1289            << QObject::tr("Address") << QObject::tr("Network Zone");
1290     m_dialog->iface_nz_list->setHorizontalHeaderLabels(labels);
1291 
1292     NetworkZoneManager netzone_manager;
1293     netzone_manager.load(mw->activeProject()->db());
1294 
1295     list<FWObject*> all_interfaces = discovered_fw->getByTypeDeep(Interface::TYPENAME);
1296     list<FWObject*>::iterator it;
1297     int row = 0;
1298     for (it=all_interfaces.begin(); it!=all_interfaces.end(); ++it)
1299     {
1300         Interface *iface = Interface::cast(*it);
1301 
1302         m_dialog->iface_nz_list->insertRow(row);
1303 
1304         QTableWidgetItem* itm;
1305 
1306         itm = new QTableWidgetItem(iface->getName().c_str());
1307         itm->setFlags(itm->flags() & ~Qt::ItemIsEditable);
1308         m_dialog->iface_nz_list->setItem(row, 0, itm);
1309 
1310         itm = new QTableWidgetItem(iface->getLabel().c_str());
1311         itm->setFlags(itm->flags() & ~Qt::ItemIsEditable);
1312         m_dialog->iface_nz_list->setItem(row, 1, itm);
1313 
1314         QString addr_str;
1315         const InetAddr* addr = iface->getAddressPtr();
1316         if (addr) addr_str = addr->toString().c_str();
1317 
1318         itm = new QTableWidgetItem(addr_str);
1319         itm->setFlags(itm->flags() & ~Qt::ItemIsEditable);
1320         m_dialog->iface_nz_list->setItem(row, 2, itm);
1321 
1322         QComboBox *widget = new QComboBox();
1323         netzone_manager.packComboBox(widget, -1);
1324         m_dialog->iface_nz_list->setCellWidget(row, 3, widget);
1325 
1326         row++;
1327     }
1328 
1329     m_dialog->iface_nz_list->resizeColumnToContents(3);
1330 }
1331 
fillNetworks()1332 void DiscoveryDruid::fillNetworks()
1333 {
1334     ObjectDescriptor buf;
1335 
1336     m_dialog->networklist->clear();
1337     bool f=false;
1338     QMap<QString,ObjectDescriptor >::iterator i;
1339     for(i=Networks.begin(); i!=Networks.end(); ++i)
1340     {
1341         buf=i.value();
1342         if (buf.isSelected)
1343         {
1344             m_dialog->networklist->addItem(new QListWidgetItem(i.key()));
1345             f=true;
1346         }
1347     }
1348     nextButton->setEnabled(f);
1349 }
1350 
fillObjects()1351 void DiscoveryDruid::fillObjects()
1352 {
1353     ObjectDescriptor buf;
1354 
1355     m_dialog->objectlist->clear();
1356     bool f=false;
1357     QMap<QString,ObjectDescriptor >::iterator i;
1358     for(i=Objects.begin(); i!=Objects.end(); ++i)
1359     {
1360         buf=i.value();
1361         if (buf.isSelected)
1362         {
1363             m_dialog->objectlist->addItem(new QListWidgetItem(i.key()));
1364             f=true;
1365         }
1366     }
1367     nextButton->setEnabled(f);
1368 }
1369 
fillTypeChangingList()1370 void DiscoveryDruid::fillTypeChangingList()
1371 {
1372 
1373     ObjectDescriptor buf;
1374 
1375     m_dialog->typeChangingList->clear();
1376 
1377     QMap<QString,ObjectDescriptor >::iterator i;
1378     for(i=Objects.begin(); i!=Objects.end(); ++i)
1379     {
1380         buf=i.value();
1381         if (buf.isSelected)
1382         {
1383             QString ins;
1384             if ( flt_last->test(buf) )
1385             {
1386                 ins=(buf.interfaces.size())?
1387                     QString("%1").arg(buf.interfaces.size()):"";
1388                 QStringList sl;
1389                 sl << buf.toString().c_str() << ins << buf.type.c_str();
1390                 new QTreeWidgetItem( m_dialog->typeChangingList, sl );
1391             }
1392         }
1393     }
1394 
1395     m_dialog->typeChangingList->resizeColumnToContents(0);
1396     m_dialog->typeChangingList->resizeColumnToContents(1);
1397 }
1398 
loadDataFromDNS()1399 void DiscoveryDruid::loadDataFromDNS()
1400 {
1401     // this is not supported since all resolver functions have been
1402     // removed from class DNS
1403 }
1404 
loadDataFromFile()1405 void DiscoveryDruid::loadDataFromFile()
1406 {
1407     m_dialog->objectresultlist->clear();
1408     int t=0;
1409     HostsFileImport *himport = dynamic_cast<HostsFileImport*>(thread);
1410     assert(himport!=NULL);
1411     int count = himport->hosts.size();
1412     if (count > 0)
1413     {
1414         int upd_max=(count > 10)?count/10:1;
1415 
1416         int updc=upd_max;
1417 
1418         QProgressDialog pd(tr("Prepare objects ..."), tr("Cancel"), 0, count,this);
1419 
1420         vector<ObjectDescriptor>::iterator i;
1421         for(i = himport->hosts.begin(); i != himport->hosts.end(); ++i)
1422         {
1423             if (i->type.empty())
1424             {
1425                 i->type=IPv4::TYPENAME;
1426             }
1427             i->isSelected=false;
1428 
1429             Objects[i->toString().c_str()] = *i;
1430             if (updc--<=0)
1431             {
1432                 pd.setValue(t);
1433                 qApp->processEvents();
1434 
1435                 if (pd.wasCanceled())
1436                 {
1437                     break;
1438                 }
1439                 updc=upd_max;
1440             }
1441             t++;
1442         }
1443     }
1444 }
1445 
loadDataFromImporter()1446 void DiscoveryDruid::loadDataFromImporter()
1447 {
1448     ConfigImport *confimp = dynamic_cast<ConfigImport*>(thread);
1449     assert(confimp!=NULL);
1450     Importer *imp = confimp->getImporterObject();
1451     if (imp!=NULL)
1452     {
1453         Firewall *fw = imp->finalize();
1454         qApp->processEvents(); // to flush the log
1455 
1456         if (fw) // fw can be NULL if import was uncussessful
1457         {
1458             discovered_fw = fw;
1459 
1460             ProjectPanel *pp = mw->activeProject();
1461             QString filename = pp->getFileName();
1462             //pp->m_panel->om->reload();
1463             //pp->m_panel->om->autoRenameChildren(fw, "");
1464 
1465             QCoreApplication::postEvent(mw, new reloadObjectTreeEvent(filename));
1466             if (mw->isEditorVisible())
1467                 QCoreApplication::postEvent(
1468                     mw, new openObjectInEditorEvent(filename, fw->getId()));
1469             QCoreApplication::postEvent(
1470                 mw, new showObjectInTreeEvent(filename, fw->getId()));
1471 
1472             // Open first created Policy ruleset object
1473             FWObject *first_policy = fw->getFirstByType(Policy::TYPENAME);
1474             if (first_policy)
1475                 QCoreApplication::postEvent(
1476                     mw, new openRulesetEvent(filename, first_policy->getId()));
1477 
1478         }
1479     }
1480 }
1481 
saveScanLog()1482 void DiscoveryDruid::saveScanLog()
1483 {
1484     QString s = QFileDialog::getSaveFileName(
1485                     this,
1486                     "Choose a file",
1487                     st->getOpenFileDir(),
1488                     "Text file (*.txt)");
1489 
1490     if (s.isEmpty()) return;
1491     st->setOpenFileDir(s);
1492 
1493     if (s.endsWith(".txt")) s += ".txt";
1494 
1495     QFile f(s);
1496     if (f.open(QIODevice::WriteOnly))
1497     {
1498         if (fwbdebug)
1499         {
1500             qDebug("Saving crawler log to file: %d chars",
1501                    m_dialog->discoverylog->toPlainText().length());
1502             qDebug("--------------------------------");
1503         }
1504 
1505         QTextStream strm(&f);
1506         QString txt = m_dialog->discoverylog->toPlainText();
1507         strm << txt << endl;
1508 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
1509         if (fwbdebug) qDebug("%s",txt.toAscii().constData());
1510 #else
1511         if (fwbdebug) qDebug("%s",txt.toLatin1().constData());
1512 #endif
1513         if (fwbdebug)
1514             qDebug("--------------------------------");
1515         f.close();
1516     }
1517 }
1518 
startSNMPScan()1519 void DiscoveryDruid::startSNMPScan()
1520 {
1521 #ifdef HAVE_LIBSNMP
1522 
1523 
1524     bool use_incl=!m_dialog->snmpinaddr->text().isEmpty() && !m_dialog->snmpinmask->text().isEmpty();
1525     if (use_incl)
1526     {
1527         try
1528         {
1529             InetAddrMask in(
1530                  InetAddr(m_dialog->snmpinaddr->text().toLatin1().constData()),
1531                  InetAddr(m_dialog->snmpinmask->text().toLatin1().constData())
1532                  );
1533             include_networks.push_back(in);
1534         }
1535         catch (const FWException &ex)
1536         {
1537             //TODO: do something usefull
1538         }
1539     }
1540     libfwbuilder::SNMPCrawler *q = new SNMPCrawler();
1541     q->init(getSeedHostAddress(),
1542             m_dialog->snmpcommunity->text().toLatin1().constData(),
1543             m_dialog->snmprecursive->isChecked(),
1544             false,
1545             m_dialog->snmpfollowp2p->isChecked(),
1546             0,
1547             m_dialog->snmpretries->value(),
1548             1000000L*m_dialog->snmptimeout->value(),
1549             0,
1550             0,
1551             (use_incl) ? &include_networks : NULL);
1552 
1553     m_dialog->discoveryprogress->setMaximum(0);
1554     unBar = m_dialog->discoveryprogress;
1555 
1556     bop=q;
1557     try
1558     {
1559         logger = bop->start_operation();
1560         if (fwbdebug) logger->copyToStderr();
1561         addToLog("Collecting data ...");
1562 
1563         disconnect(timer, SIGNAL(timeout()), 0, 0);
1564         connect(timer, SIGNAL(timeout()), this, SLOT(updateLog()));
1565         timer->setSingleShot(false);
1566         timer->start(100);
1567 
1568     } catch(const FWException &ex)
1569     {
1570         delete q;
1571         q=NULL;
1572     }
1573 
1574 
1575 #endif
1576 }
1577 
loadDataFromCrawler()1578 void DiscoveryDruid::loadDataFromCrawler()
1579 {
1580 #ifdef HAVE_LIBSNMP
1581     SNMPCrawler *q=(SNMPCrawler*)bop;
1582     Objects.clear();
1583     Networks.clear();
1584 
1585     set<InetAddrMask*>::iterator m;
1586     set<InetAddrMask*> discovered_networks = q->getNetworks();
1587 
1588     if (fwbdebug)
1589         qDebug() << QString("got %1 networks").arg(discovered_networks.size());
1590 
1591     for (m=discovered_networks.begin(); m!=discovered_networks.end(); ++m)
1592     {
1593         ObjectDescriptor od;
1594         InetAddrMask *net = *m;
1595 
1596         if (fwbdebug)
1597             qDebug() << QString("network %1").arg(net->toString().c_str());
1598 
1599         // if address in *m is ipv6, recreate it as Inet6AddrMask and
1600         // use type NetworkIPv6
1601         if (net->getAddressPtr()->isV6())
1602         {
1603             Inet6AddrMask in6am(*(net->getAddressPtr()),
1604                                 *(net->getNetmaskPtr()));
1605             od.sysname = in6am.toString(); // different from ipv6
1606             od.type = NetworkIPv6::TYPENAME;
1607         } else
1608         {
1609             od.sysname = net->toString();
1610             od.type = Network::TYPENAME;
1611         }
1612         od.addr = *(net->getAddressPtr());
1613         od.netmask = *(net->getNetmaskPtr());
1614         od.isSelected = false;
1615         Networks[od.sysname.c_str()]= od;
1616     }
1617 
1618     map<InetAddr, CrawlerFind>  t = q->getAllIPs();
1619 
1620     if (fwbdebug)
1621         qDebug() << QString("got %1 addresses").arg(t.size());
1622 
1623     m_dialog->discoveryprogress->setMaximum( t.size() );
1624     m_dialog->discoveryprogress->setValue(0);
1625 
1626     int cntr = 0;
1627     map<InetAddr, CrawlerFind>::iterator j;
1628     for(j = t.begin(); j!=t.end(); ++j,++cntr)
1629     {
1630         m_dialog->discoveryprogress->setValue( cntr );
1631 
1632         ObjectDescriptor od( (*j).second );
1633         od.addr     = (*j).first;
1634         od.type=(od.interfaces.size()>1)?
1635             (Host::TYPENAME):(IPv4::TYPENAME);
1636 
1637         od.isSelected=false;
1638 
1639         if (od.sysname.empty())
1640         {
1641             od.sysname = string("h-") + od.addr.toString();
1642             if (m_dialog->snmpdodns->isChecked())
1643             {
1644                 QString hostName = getNameByAddr( od.addr.toString().c_str() );
1645                 if (!hostName.isEmpty())
1646                     od.sysname = hostName.toLatin1().constData();
1647             }
1648 
1649             addToLog(
1650                 QString(od.addr.toString().c_str()) + " : " + od.sysname.c_str());
1651 
1652         }
1653 
1654         Objects[od.toString().c_str()]=od;
1655 
1656         set<string>::iterator si;
1657         for(si=od.dns_info.aliases.begin();
1658                 si!=od.dns_info.aliases.end();
1659                 ++si)
1660         {
1661             od.sysname=(*si);
1662             Objects[od.toString().c_str()]=od;
1663         }
1664     }
1665 #endif
1666 }
1667 
1668 
1669 
fillListOfNetworks()1670 void DiscoveryDruid::fillListOfNetworks()
1671 {
1672     m_dialog->networkresultlist->clear();
1673     int t=0;
1674     int count = Networks.size();
1675     if (count > 0)
1676     {
1677         int upd_max=(count > 10)?count/10:1;
1678 
1679         int updc=upd_max;
1680 
1681         QProgressDialog pd(tr("Copying results ..."), tr("Cancel"), 0, count,this);
1682 
1683         QMap<QString, ObjectDescriptor>::iterator i;
1684         for (i=Networks.begin(); i!=Networks.end(); ++i)
1685         {
1686 
1687             if ( flt_net->test(i.value()) )
1688             {
1689 
1690                 m_dialog->networkresultlist->addItem(new QListWidgetItem(i.key()));
1691                 if (updc--<=0)
1692                 {
1693                     pd.setValue(t);
1694                     qApp->processEvents();
1695 
1696                     if (pd.wasCanceled())
1697                     {
1698                         break;
1699                     }
1700                     updc=upd_max;
1701                 }
1702             }
1703             t++;
1704         }
1705     }
1706 }
1707 
fillListOfObjects()1708 void DiscoveryDruid::fillListOfObjects()
1709 {
1710 
1711     m_dialog->objectresultlist->clear();
1712     int t=0;
1713     int count = Objects.size();
1714     if (count > 0)
1715     {
1716         int upd_max=(count > 10)?count/10:1;
1717 
1718         int updc=upd_max;
1719 
1720         QProgressDialog pd(tr("Copying results ..."),
1721                            tr("Cancel"), 0,count,this);
1722 
1723         QMap<QString,ObjectDescriptor >::iterator i;
1724         for(i=Objects.begin(); i!=Objects.end(); ++i)
1725         {
1726             if ( flt_obj->test(i.value()) )
1727             {
1728 
1729                 m_dialog->objectresultlist->addItem(new QListWidgetItem(i.key()));
1730                 if (updc--<=0)
1731                 {
1732                     pd.setValue(t);
1733                     qApp->processEvents();
1734 
1735                     if (pd.wasCanceled())
1736                     {
1737                         break;
1738                     }
1739                     updc=upd_max;
1740                 }
1741             }
1742             t++;
1743         }
1744     }
1745 }
1746 
customEvent(QEvent * event)1747 void DiscoveryDruid::customEvent(QEvent *event)
1748 {
1749     int evtype=(int)event->type();
1750     if (evtype == ProgressEv)
1751     {
1752         ProgressEvent *e = (ProgressEvent*)event;
1753         m_dialog->discoveryprogress->setValue(e->value);
1754     } else if (evtype == DoneEv)
1755     {
1756         cancelButton->show();
1757 
1758         timer->stop();
1759         disconnect(timer,SIGNAL(timeout()),0,0);
1760 
1761         updateLog();
1762         m_dialog->logSaveButton->setEnabled(true);
1763 
1764         // actually create objects
1765         switch (current_task)
1766         {
1767         case BT_HOSTS:
1768             loadDataFromFile();
1769             break;
1770 
1771         case BT_IMPORT:
1772             loadDataFromImporter();
1773             break;
1774 
1775         default:
1776             break;
1777         }
1778 
1779         thread->wait();
1780         QString er = thread->getError();
1781         delete thread;
1782         thread=NULL;
1783 
1784         switch (current_task)
1785         {
1786         case BT_HOSTS:
1787             if (Objects.size()>0)
1788             {
1789                 nextButton->setDefault(true);
1790                 nextButton->setFocus();
1791                 nextButton->setEnabled(true);
1792                 backButton->setEnabled(false);
1793             }
1794             else
1795             {
1796                 backButton->setEnabled(true);
1797                 nextButton->setEnabled(false);
1798             }
1799             break;
1800 
1801         case BT_IMPORT:
1802         {
1803             // if imported PIX, need to show one more page to select network zones
1804             if (selectedPlatform() == "pix")
1805             {
1806                 setNextEnabled(currentPage(), true);
1807                 setFinishEnabled(currentPage(), false);
1808             } else
1809             {
1810                 setNextEnabled(currentPage(), false);
1811                 setFinishEnabled(currentPage(), true);
1812                 finishButton->setFocus();
1813             }
1814             break;
1815         }
1816         default:
1817             break;
1818         }
1819 
1820     }
1821 }
1822 
updateLog()1823 void DiscoveryDruid::updateLog()
1824 {
1825     if (fwbdebug) qDebug("DiscoveryDruid::updateLog");
1826 
1827     if (current_task==BT_HOSTS || current_task==BT_IMPORT)
1828     {
1829         QString buf;
1830         if (thread!=NULL)
1831         {
1832             while(thread->Log->ready())
1833             {
1834                 buf = thread->Log->getLine().c_str();
1835                 addToLog(buf);
1836             }
1837         }
1838     }
1839     else if (current_task==BT_SNMP)
1840     {
1841        if (monitorOperation() > 0)
1842        {
1843 
1844            //m_dialog->discoveryprogress->setValue(prg++);
1845        }
1846        else
1847        {
1848             timer->stop();
1849             disconnect(timer,SIGNAL(timeout()),0,0);
1850 
1851             if (fwbdebug) qDebug("Crawler finished");
1852 
1853             loadDataFromCrawler();
1854 
1855             cancelButton->show();
1856 
1857             FWException * ex=bop->get_latest_error();
1858             if (ex!=NULL)
1859             {
1860                 QMessageBox::critical(this,
1861                                       tr("Discovery error"),
1862                                       ex->toString().c_str());
1863             }
1864             if (Objects.size()>0 || Networks.size()>0)
1865             {
1866                 if (Networks.size()==0) setAppropriate( 8,0);
1867                 nextButton->setEnabled(true);
1868                 nextButton->setDefault(true);
1869                 nextButton->setFocus();
1870                 backButton->setEnabled(false);
1871             }
1872             else
1873             {
1874                 nextButton->setEnabled(false);
1875                 backButton->setEnabled(true);
1876             }
1877 
1878             m_dialog->logSaveButton->setEnabled(true);
1879 
1880             delete bop;
1881             bop=NULL;
1882             unBar=NULL;
1883             m_dialog->discoveryprogress->setMaximum(100);
1884             m_dialog->discoveryprogress->setValue(100);
1885             m_dialog->discoveryStopButton->setEnabled(false);
1886        }
1887     }
1888     else if (current_task==BT_DNS)
1889     {
1890        if (monitorOperation() > 0)
1891        {
1892            //m_dialog->discoveryprogress->setMaximum(0);
1893            //m_dialog->discoveryprogress->setValue(
1894            //        m_dialog->discoveryprogress->progress()+1);
1895        }
1896        else
1897        {
1898             timer->stop();
1899             disconnect(timer,SIGNAL(timeout()),0,0);
1900 
1901             loadDataFromDNS();
1902 
1903             cancelButton->show();
1904             FWException * ex=bop->get_latest_error();
1905             if (ex!=NULL)
1906             {
1907                 QMessageBox::critical(this, tr("Discovery error"),
1908                                       ex->toString().c_str());
1909             }
1910             if (Objects.size()>0)
1911             {
1912                 nextButton->setEnabled(true);
1913                 nextButton->setDefault(true);
1914                 nextButton->setFocus();
1915                 backButton->setEnabled(false);
1916             }
1917             else
1918             {
1919                 nextButton->setEnabled(false);
1920                 backButton->setEnabled(true);
1921             }
1922             m_dialog->logSaveButton->setEnabled(true);
1923             delete bop;
1924             bop=NULL;
1925             unBar=NULL;
1926             m_dialog->discoveryprogress->setMaximum(100);
1927             m_dialog->discoveryprogress->setValue(100);
1928             m_dialog->discoveryStopButton->setEnabled(false);
1929        }
1930     }
1931 }
1932 
addToLog(const QString & buf)1933 void DiscoveryDruid::addToLog(const QString &buf)
1934 {
1935     if (buf.isEmpty()) return;
1936 
1937     foreach(QString line, buf.trimmed().split("\n"))
1938     {
1939         QTextCharFormat format = normal_format;
1940 
1941         if (line.contains("Parser error"))
1942             format = error_format;
1943 
1944         if (line.contains("Parser warning"))
1945             format = warning_format;
1946 
1947         if (line.contains("SNMP error, status 2 Timeout"))
1948             format = warning_format;
1949 
1950         QString txt = line;
1951         while (!txt.isEmpty() && (txt.endsWith("\n") || txt.endsWith("\r")))
1952             txt.chop(1);
1953 
1954         if (format == error_format || format == warning_format)
1955             format.setAnchorHref(txt);
1956 
1957         QTextCursor cursor = m_dialog->discoverylog->textCursor();
1958         cursor.insertBlock();
1959         cursor.insertText(txt, format);
1960     }
1961 
1962     m_dialog->discoverylog->ensureCursorVisible();
1963 }
1964 
changedSeedHost()1965 void DiscoveryDruid::changedSeedHost()
1966 {
1967     m_dialog->seedhosterror_message->setText(" ");
1968     userIsTyping = true;
1969     errMessage = m_dialog->seedhosterror_message;
1970     HostName = m_dialog->seedhostname->text();
1971 
1972     if (HostName.isEmpty())
1973     {
1974         timer->stop();
1975         m_dialog->DNSprogress->hide();
1976         QPalette palette = m_dialog->seedhosterror_message->palette();
1977         palette.setColor(
1978             m_dialog->seedhosterror_message->foregroundRole(), Qt::darkRed);
1979         m_dialog->seedhosterror_message->setPalette(palette);
1980 
1981         m_dialog->seedhosterror_message->setText(
1982             "Enter a valid host name or address.");
1983         isSeedHostOK=false;
1984     }
1985     else
1986     {
1987         if(isInetAddr(HostName))
1988         { // seems to be an IP Address
1989             m_dialog->DNSprogress->hide();
1990             timer->stop();
1991             QRegExp r = QRegExp(
1992                 "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$",
1993                 Qt::CaseInsensitive); //non wildcard
1994             if (r.exactMatch(HostName))
1995             {
1996                 try
1997                 {
1998                     InetAddr(HostName.toLatin1().constData());
1999 
2000                     QPalette palette =
2001                         m_dialog->seedhosterror_message->palette();
2002                     palette.setColor(
2003                         m_dialog->seedhosterror_message->foregroundRole(),
2004                         Qt::darkGreen);
2005                     m_dialog->seedhosterror_message->setPalette(palette);
2006 
2007                     m_dialog->seedhosterror_message->setText(
2008                         "Address verified");
2009                     isSeedHostOK=true;
2010                 } catch(const FWException &ex)
2011                 {
2012                     QPalette palette =
2013                         m_dialog->seedhosterror_message->palette();
2014                     palette.setColor(
2015                         m_dialog->seedhosterror_message->foregroundRole(),
2016                         Qt::darkRed);
2017                     m_dialog->seedhosterror_message->setPalette(palette);
2018 
2019                     m_dialog->seedhosterror_message->setText(
2020                         ex.toString().c_str());
2021                     // need to return focus to the input field in case of error
2022                     //m_dialog->seedhostname->setFocus();
2023                     isSeedHostOK=false;
2024                 }
2025             }
2026             else
2027             {
2028                 QPalette palette = m_dialog->seedhosterror_message->palette();
2029                 palette.setColor(
2030                     m_dialog->seedhosterror_message->foregroundRole(),
2031                     Qt::darkRed);
2032                 m_dialog->seedhosterror_message->setPalette(palette);
2033 
2034                 m_dialog->seedhosterror_message->setText("Wrong IPv4 format");
2035                 isSeedHostOK=false;
2036 
2037             }
2038         }
2039         else
2040         {// it looks like a DNS name
2041             isSeedHostOK = false;
2042 
2043             QPalette palette = m_dialog->seedhosterror_message->palette();
2044             palette.setColor(
2045                 m_dialog->seedhosterror_message->foregroundRole(), Qt::black);
2046             m_dialog->seedhosterror_message->setPalette(palette);
2047 
2048             m_dialog->seedhosterror_message->setText(
2049                 "DNS resolution in progress...");
2050             unProg = 0;
2051             unBar=m_dialog->DNSprogress;
2052 
2053             errMessage=m_dialog->seedhosterror_message;
2054             m_dialog->DNSprogress->show();
2055             timer->setSingleShot(true);
2056             timer->start(1000);
2057         }
2058     }
2059     nextButton->setEnabled(isSNMPInclNetOK && isSeedHostOK);
2060 }
2061 
changedInclNet()2062 void DiscoveryDruid::changedInclNet()
2063 {
2064     setNextEnabled(currentPage(),false);
2065     m_dialog->confineerror_message->setText(" ");
2066     bool use_incl=!m_dialog->snmpinaddr->text().isEmpty() && !m_dialog->snmpinmask->text().isEmpty();
2067     if (use_incl)
2068     {
2069         try
2070         {
2071 
2072             InetAddr a(m_dialog->snmpinaddr->text().toLatin1().constData());
2073             InetAddr n(m_dialog->snmpinmask->text().toLatin1().constData());
2074             InetAddrMask(a,n);
2075 
2076             m_dialog->confineerror_message->setText(" ");
2077             isSNMPInclNetOK=true;
2078         } catch (const FWException &ex)
2079         {
2080             isSNMPInclNetOK=false;
2081             m_dialog->confineerror_message->setText(ex.toString().c_str());
2082         }
2083 
2084     }
2085     else
2086     {
2087         if (!m_dialog->snmpinaddr->text().isEmpty() || !m_dialog->snmpinmask->text().isEmpty())
2088         {
2089             isSNMPInclNetOK=false;
2090             m_dialog->confineerror_message->setText(tr("Incomlete network specification."));
2091         }
2092         else
2093         {
2094             m_dialog->confineerror_message->setText(" ");
2095             isSNMPInclNetOK=true;
2096         }
2097     }
2098     nextButton->setEnabled(isSNMPInclNetOK && isSeedHostOK);
2099 }
2100 
monitorOperation()2101 int DiscoveryDruid::monitorOperation()
2102 {
2103     QString buf;
2104     bool fl;
2105 
2106     if (fwbdebug) qDebug("monitorOperation  bop=%p  isRunning=%d",
2107                          bop,(bop!=NULL)?bop->isRunning():-1);
2108 
2109 
2110     fl=false;
2111     while( logger->ready() )
2112     {
2113         buf= logger->getLine().c_str();
2114         if (buf.endsWith('\n'))
2115             buf = buf.left(buf.length() - 1);
2116 
2117         addToLog(buf);
2118 
2119         /*if (fwbdebug) qDebug("monitorOperation  appending the following buf: (1)");
2120 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2121         if (fwbdebug) qDebug(buf.toAscii().constData());
2122 #else
2123         if (fwbdebug) qDebug(buf.toLatin1().constData());
2124 #endif
2125         if (fwbdebug) qDebug("----------------------------------------------");*/
2126 
2127         fl=true;
2128     }
2129     if (fl)
2130     {
2131         return 1;
2132     }
2133     if (bop==NULL)
2134     {
2135 
2136         return 0; // BackgroundOp has been disconnected
2137     }
2138 
2139     if (bop->isRunning())
2140     {
2141         return 1;
2142     }
2143     // send signal "completed", argument is 0 if ok and -1 if error
2144 
2145 
2146     FWException *ex=bop->get_latest_error();
2147     if (ex)
2148     {
2149         buf= ex->toString().c_str();
2150         if (buf.endsWith('\n'))
2151             buf = buf.left(buf.length() - 1);
2152 
2153         addToLog(buf);
2154 
2155         /*if (fwbdebug) qDebug("monitorOperation  appending the following buf: (2)");
2156 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2157         if (fwbdebug) qDebug(buf.toAscii().constData());
2158 #else
2159         if (fwbdebug) qDebug(buf.toLatin1().constData());
2160 #endif
2161         if (fwbdebug) qDebug("----------------------------------------------");*/
2162 
2163       //  completed(-1);   // this sends signal to another widget
2164     } else
2165     {
2166       //  completed(0);   // this sends signal to another widget
2167     }
2168     return 0;
2169 
2170 }
2171 
checkHostName()2172 void DiscoveryDruid::checkHostName()
2173 {
2174     if (!HostName.isEmpty())
2175     {
2176         userIsTyping=false;
2177         QHostInfo::lookupHost(HostName,
2178                               this, SLOT(dnsFinish(QHostInfo)));
2179     }
2180 }
2181 
checkSNMPCommunity()2182 void DiscoveryDruid::checkSNMPCommunity()
2183 {
2184     if (m_dialog->snmpcommunity->text().isEmpty())
2185     {
2186         m_dialog->snmpcommunity_message->setText(tr("Empty community string"));
2187         setNextEnabled(currentPage(),false);
2188     }
2189     else
2190     {
2191         m_dialog->snmpcommunity_message->setText("");
2192         setNextEnabled(currentPage(),true);
2193     }
2194 }
2195 
changeTargetObject(const QString & buf)2196 void DiscoveryDruid::changeTargetObject(const QString &buf)
2197 {
2198 
2199     QTreeWidgetItem* item=m_dialog->typeChangingList->topLevelItem(0);
2200 
2201     while (item!=0)
2202     {
2203         if (item->isSelected())
2204         {
2205             Objects[item->text(0)].type=buf.toLatin1().constData();
2206             item->setText(2,buf);
2207         }
2208         item=m_dialog->typeChangingList->topLevelItem(
2209                 m_dialog->typeChangingList->indexOfTopLevelItem(item)+1);
2210     }
2211 }
2212 
selectAllLast()2213 void DiscoveryDruid::selectAllLast()
2214 {
2215     m_dialog->typeChangingList->selectAll();
2216 }
2217 
unselectAllLast()2218 void DiscoveryDruid::unselectAllLast()
2219 {
2220     m_dialog->typeChangingList->selectAll();
2221 }
2222 
typeAddress()2223 void DiscoveryDruid::typeAddress()
2224 {
2225     changeTargetObject(IPv4::TYPENAME);
2226 }
2227 
typeHost()2228 void DiscoveryDruid::typeHost()
2229 {
2230     changeTargetObject(Host::TYPENAME);
2231 }
2232 
typeFirewall()2233 void DiscoveryDruid::typeFirewall()
2234 {
2235     changeTargetObject(Firewall::TYPENAME);
2236 }
2237 
2238 /*
2239  * Guess OS from the sysDescr string returned by the host. Returned OS
2240  * name is always lower case one word, such as "linux", "ios"
2241  *
2242  * Examples of sysDescr strings:
2243  *
2244  * IOS (tm) 3600 Software (C3620-IK9O3S-M), Version 12.2(13), RELEASE SOFTWARE (fc1)
2245  * Linux guardian 2.4.20 #2 Wed Nov 17 11:49:43 CET 2004 mips
2246  * Linux crash 2.6.24-22-server #1 SMP Mon Nov 24 20:06:28 UTC 2008 x86_64
2247  * Apple AirPort - Apple Computer, 2006.  All rights Reserved
2248  * Cisco Secure FWSM Firewall Version 2.3(4)
2249  * Cisco PIX Firewall Version 6.2(1)
2250  * Cisco Adaptive Security Appliance Version 8.2(0)227
2251  */
guessOS(const string & sysDescr)2252 QString DiscoveryDruid::guessOS(const string &sysDescr)
2253 {
2254     QStringList elements = QString(sysDescr.c_str()).split(" ");
2255     QString first = elements[0].toLower();
2256     if (first == "cisco")
2257     {
2258         if (elements[1].toLower() == "adaptive" &&
2259             elements[2].toLower() == "security" &&
2260             elements[3].toLower() == "appliance") return "pix";
2261         if (elements[1].toLower() == "pix") return "pix";
2262         if (elements[1].toLower() == "secure" &&
2263             elements[2].toLower() == "fwsm") return "pix";
2264     }
2265     if (first == "darwin") return "macosx";
2266     if (first == "apple") return "macosx";
2267 
2268     return first;
2269 }
2270 
2271 
addInterface(FWObject * parent,InterfaceData * in,bool skip_ip_address_check)2272 FWObject* DiscoveryDruid::addInterface(FWObject *parent, InterfaceData *in,
2273                                        bool skip_ip_address_check)
2274 {
2275     ObjectManipulator *om = mw->activeProject()->m_panel->om;
2276 
2277     if (!m_dialog->snmpincludeunnumbered->isChecked() && !skip_ip_address_check)
2278     {
2279         if (in->addr_mask.size()==0) return NULL;
2280         if (in->addr_mask.front()->getAddressPtr()->isAny())
2281             return NULL;
2282     }
2283 
2284     QString obj_name = in->name.c_str();
2285     Interface *itf = NULL;
2286     itf = Interface::cast(
2287         mw->createObject(parent,
2288                          QString(Interface::TYPENAME), obj_name));
2289 
2290     QString iname = om->getStandardName(itf, physAddress::TYPENAME, "mac");
2291     iname = om->makeNameUnique(itf, iname, physAddress::TYPENAME);
2292 
2293     physAddress *paddr = physAddress::cast(
2294         mw->createObject(itf, physAddress::TYPENAME, iname)
2295     );
2296     paddr->setPhysAddress(in->mac_addr);
2297 
2298     itf->setLabel(in->label);
2299     itf->setSecurityLevel(in->securityLevel);
2300 
2301     if (fwbdebug)
2302         qDebug() << "Interface=" << obj_name
2303                  << "type=" << in->interface_type.c_str();
2304 
2305     if (!in->interface_type.empty())
2306     {
2307         itf->getOptionsObject()->setStr("type", in->interface_type);
2308         if (in->interface_type == "8021q")
2309             itf->getOptionsObject()->setInt("vlan_id", in->vlan_id);
2310     } else
2311     {
2312         std::auto_ptr<interfaceProperties> int_prop(
2313             interfacePropertiesObjectFactory::getInterfacePropertiesObject(parent));
2314         if (int_prop->looksLikeVlanInterface(obj_name))
2315         {
2316             QString base_name;
2317             int vlan_id;
2318             int_prop->parseVlan(obj_name, &base_name, &vlan_id);
2319 
2320             itf->getOptionsObject()->setStr("type", "8021q");
2321             itf->getOptionsObject()->setInt("vlan_id", vlan_id);
2322         }
2323     }
2324 
2325     if (in->addr_mask.size()==0 ||
2326         in->addr_mask.front()->getAddressPtr()->isAny())
2327     {
2328         itf->setUnnumbered(true);
2329     } else
2330     {
2331         list<InetAddrMask*>::iterator n;
2332         for (n=in->addr_mask.begin(); n!=in->addr_mask.end(); ++n)
2333         {
2334             const InetAddr *addr = (*n)->getAddressPtr();
2335             const InetAddr *netm = (*n)->getNetmaskPtr();
2336 
2337             if (addr->isV4())
2338             {
2339                 try
2340                 {
2341                     QString iname = om->getStandardName(itf, IPv4::TYPENAME, "ip");
2342                     iname = om->makeNameUnique(itf, iname, IPv4::TYPENAME);
2343 
2344                     IPv4 *ipv4= IPv4::cast(
2345                         om->createObject(itf, IPv4::TYPENAME, iname)
2346                     );
2347                     ipv4->setAddress(*addr);
2348                     ipv4->setNetmask(*netm);
2349                 } catch (FWException &ex)
2350                 {
2351                     cerr << "FWException: " << ex.toString() << endl;
2352                 }
2353             }
2354 
2355             if (addr->isV6())
2356             {
2357                 try
2358                 {
2359                     QString iname = om->getStandardName(itf, IPv6::TYPENAME, "ip");
2360                     iname = om->makeNameUnique(itf, iname, IPv6::TYPENAME);
2361 
2362                     IPv6 *ipv6 = IPv6::cast(
2363                         om->createObject(itf, IPv6::TYPENAME, iname)
2364                     );
2365                     ipv6->setAddress(*addr);
2366                     ipv6->setNetmask(*netm);
2367                 } catch (FWException &ex)
2368                 {
2369                     cerr << "FWException: " << ex.toString() << endl;
2370                 }
2371             }
2372         }
2373     }
2374     return itf;
2375 }
2376 
createRealObjects()2377 void DiscoveryDruid::createRealObjects()
2378 {
2379     ObjectDescriptor od;
2380     string type, name, a;
2381 
2382     int t=0;
2383     m_dialog->lastprogress->setValue(0);
2384     m_dialog->lastprogress->setMaximum( Objects.size());
2385 
2386     QMap<QString,ObjectDescriptor >::iterator i;
2387     for (i=Networks.begin(); i!=Networks.end(); ++i)
2388     {
2389         od=i.value();
2390         if (od.isSelected)
2391         {
2392             type = od.type; // Network or NetworkIPv6
2393             name = od.sysname;
2394             a = od.addr.toString().c_str();
2395 
2396             Address *net = Address::cast(
2397                 mw->createObject(type.c_str(), name.c_str()));
2398             assert(net!=NULL);
2399             net->setName(name);
2400             net->setAddress(od.addr);
2401             net->setNetmask(od.netmask);
2402 
2403             mw->moveObject(m_dialog->libs->currentText(), net);
2404         }
2405     }
2406 
2407     for (i=Objects.begin(); i!=Objects.end(); ++i)
2408     {
2409         od = i.value();
2410         type = od.type;
2411 
2412         name = od.sysname;
2413 
2414         QString os = guessOS(od.descr);
2415 
2416         a = od.addr.toString();
2417 
2418         if (od.isSelected)
2419         {
2420             if (type==Host::TYPENAME || type==Firewall::TYPENAME)
2421             {
2422                 FWObject *o=NULL;
2423 
2424                 o = mw->createObject(type.c_str(), name.c_str());
2425                 o->setName(name);
2426 
2427                 if (type==Firewall::TYPENAME)
2428                 {
2429                     if (os == "linux")
2430                     {
2431                         o->setStr("platform", "iptables");
2432                         o->setStr("host_OS", "linux24");
2433                     }
2434                     if (os == "freebsd")
2435                     {
2436                         o->setStr("platform", "pf");
2437                         o->setStr("host_OS", "freebsd");
2438                     }
2439                     if (os == "openbsd")
2440                     {
2441                         o->setStr("platform", "pf");
2442                         o->setStr("host_OS", "openbsd");
2443                     }
2444                     if (os == "ios")
2445                     {
2446                         o->setStr("platform", "iosacl");
2447                         o->setStr("host_OS", "ios");
2448                     }
2449                     if (os == "pix" || os == "fwsm")
2450                     {
2451                         o->setStr("platform", "pix");
2452                         o->setStr("host_OS", "pix_os");
2453                     }
2454                     if (os == "apple")
2455                     {
2456                         o->setStr("platform", "ipfw");
2457                         o->setStr("host_OS", "macosx");
2458                     }
2459                     if (os == "solaris")
2460                     {
2461                         o->setStr("platform", "ipf");
2462                         o->setStr("host_OS", "solaris");
2463                     }
2464 
2465                     Resources::setDefaultTargetOptions( o->getStr("platform"),
2466                                                         Firewall::cast(o) );
2467                     Resources::setDefaultTargetOptions( o->getStr("host_OS"),
2468                                                         Firewall::cast(o) );
2469                 }
2470 
2471                 if (od.interfaces.size()==0)
2472                 {
2473                     Interface *itf= Interface::cast(
2474                         mw->createObject(o,Interface::TYPENAME,"nic1")
2475                     );
2476 
2477                     if (od.addr.isV4())
2478                     {
2479                         IPv4 *ipv4= IPv4::cast(
2480                             mw->createObject(itf, IPv4::TYPENAME, a.c_str())
2481                         );
2482                         ipv4->setAddress(od.addr);
2483                         ipv4->setNetmask(InetAddr());
2484                     }
2485 
2486                     if (od.addr.isV6())
2487                     {
2488                         IPv6 *ipv6 = IPv6::cast(
2489                             mw->createObject(itf, IPv6::TYPENAME, a.c_str())
2490                         );
2491                         ipv6->setAddress(od.addr);
2492                         ipv6->setNetmask(InetAddr());
2493                     }
2494 
2495                 } else
2496                 {
2497                     if (fwbdebug)
2498                     {
2499                         map<int,InterfaceData>::iterator i;
2500                         for (i=od.interfaces.begin(); i!=od.interfaces.end(); ++i)
2501                         {
2502                             InterfaceData *intf = &(i->second);
2503                             QString str("Discovered interface %1: %2");
2504                             qDebug() <<
2505                                 str.arg(intf->name.c_str()).arg(intf->mac_addr.c_str());
2506 
2507                         }
2508                     }
2509 
2510                     list<InterfaceData*> interface_tree;
2511                     std::auto_ptr<interfaceProperties> int_prop(
2512                         interfacePropertiesObjectFactory::getInterfacePropertiesObject(o));
2513                     int_prop->rearrangeInterfaces(od.interfaces, interface_tree);
2514 
2515                     if (interface_tree.size() != od.interfaces.size())
2516                     {
2517                         // Some interfaces have been converted to subinterfaces
2518                         // Show warning
2519 
2520                         QMessageBox::warning(
2521                             this, "Firewall Builder",
2522                             tr(
2523 "Some discovered interfaces have been rearranged in "
2524 "fwbuilder objects and recreated as subinterfaces to "
2525 "reflect VLANs, bonding and bridging configurations. "
2526 "The algorithm used to guess correct relationship "
2527 "between interfaces and subinterfaces is imperfect "
2528 "because of the limited information provided by SNMP "
2529 "daemon. Pelase review created objects to make sure "
2530 "generated configuration is accurate. "
2531 "\n"
2532 "\n"
2533 "The program expects MAC addresses of bonding, bridge "
2534 "and vlan interfaces to be the same. It is especially "
2535 "important to review and fix generated objects if you "
2536 "use MAC address spoofing."
2537 ),
2538                             tr("&Continue"), 0, 0,
2539                             0 );
2540 
2541 
2542                     }
2543 
2544                     list<InterfaceData*>::iterator it;
2545                     for (it=interface_tree.begin(); it!=interface_tree.end(); ++it)
2546                     {
2547                         InterfaceData *in = *it;
2548                         // if this interface has subinterfaces, add even if it
2549                         // has no ip address (last arg)
2550 
2551                         FWObject *intf = addInterface(
2552                             o, in, in->subinterfaces.size()!=0);
2553                         if (intf == NULL) continue;
2554 
2555                         list<InterfaceData*>::iterator sit;
2556                         for (sit=in->subinterfaces.begin();
2557                              sit!=in->subinterfaces.end(); ++sit)
2558                         {
2559                             InterfaceData *subint = *sit;
2560                             addInterface(intf, subint, true);
2561                         }
2562                     }
2563                 }
2564 
2565                 if (!od.descr.empty())
2566                 {
2567                     FWOptions* opt=(dynamic_cast<Host*>(o))->getOptionsObject();
2568                     opt->setStr("snmp_description",od.descr);
2569                     opt->setStr("snmp_location",   od.location);
2570                     opt->setStr("snmp_contact",    od.contact);
2571                 }
2572 
2573                 mw->moveObject(m_dialog->libs->currentText(), o);
2574 
2575             } else if (type==Network::TYPENAME)
2576             {
2577                 Network *net=dynamic_cast<Network*>(
2578                     mw->createObject(type.c_str(),name.c_str())
2579                 );
2580                 assert(net!=NULL);
2581                 net->setName(name);
2582                 net->setAddress(InetAddr(a));
2583                 net->setNetmask(InetAddr(InetAddr(a)));
2584                 mw->moveObject(m_dialog->libs->currentText(), net);
2585             } else if (type==IPv4::TYPENAME)
2586             {
2587                 IPv4 *obj=dynamic_cast<IPv4*>(
2588                     mw->createObject(type.c_str(),name.c_str())
2589                 );
2590                 assert(obj!=NULL);
2591                 obj->setName(name);
2592                 obj->setAddress(InetAddr(a));
2593                 obj->setNetmask(InetAddr(InetAddr::getAllOnes()));
2594                 mw->moveObject(m_dialog->libs->currentText(), obj);
2595             }
2596         }
2597         m_dialog->lastprogress->setValue(t++);
2598         qApp->processEvents();
2599     }
2600     m_dialog->lastprogress->setValue(Objects.size());
2601 
2602     ProjectPanel *pp = mw->activeProject();
2603     QString filename = pp->getFileName();
2604 
2605     QCoreApplication::postEvent(mw, new reloadObjectTreeEvent(filename));
2606 
2607 }
2608 
importPlatformChanged(int cp)2609 void DiscoveryDruid::importPlatformChanged(int cp)
2610 {
2611     if (fwbdebug)
2612         qDebug("DiscoveryDruid::importPlatformChanged(): %d",cp);
2613 
2614     switch (cp)
2615     {
2616     case IMPORT_IOS:
2617         m_dialog->import_text->setText(
2618             QObject::tr("Firewall Builder can import Cisco IOS access lists "
2619                         "from the router configuration saved using 'show run' "
2620                         "or any other command that saves running config. The name "
2621                         "of the created firewall object, all of its interfaces "
2622                         "and their addresses will be configured automatically if "
2623                         "this information can be found in the configuration file."
2624             )
2625         );
2626         break;
2627 
2628     case IMPORT_PIX:
2629         m_dialog->import_text->setText(
2630             QObject::tr("Firewall Builder can import Cisco PIX and ASA "
2631                         "configuration saved with 'show run' command.  "
2632                         "The name of the created firewall object, all of "
2633                         "its interfaces and their addresses will be "
2634                         "configured automatically if this information can "
2635                         "be found in the configuration file."
2636             )
2637         );
2638         break;
2639 
2640     case IMPORT_IPT:
2641         m_dialog->import_text->setText(
2642             QObject::tr("Firewall Builder can import iptables rules "
2643                         "from a file in iptables-save format. Firewall "
2644                         "name and addresses of its interfaces need "
2645                         "to be configured manually because iptables-save "
2646                         "file does not have this information. "
2647             )
2648         );
2649         break;
2650 
2651     }
2652 
2653 }
2654 
2655 //----------------------------------------------------------------------
ObjectDescriptor()2656 ObjectDescriptor::ObjectDescriptor() {}
2657 
ObjectDescriptor(const ObjectDescriptor & od)2658 ObjectDescriptor::ObjectDescriptor(const ObjectDescriptor& od) {
2659     have_snmpd       = od.have_snmpd;
2660     descr            = od.descr;
2661     contact          = od.contact;
2662     location         = od.location;
2663     sysname          = od.sysname;
2664     interfaces       = od.interfaces;
2665     MAC_addr         = od.MAC_addr;
2666     dns_info.name    = od.dns_info.name;
2667     dns_info.aliases = od.dns_info.aliases;
2668     addr             = od.addr;
2669     type             = od.type;
2670     isSelected       = od.isSelected;
2671     netmask          = od.netmask;
2672 
2673 }
2674 
2675 #ifdef HAVE_LIBSNMP
ObjectDescriptor(const libfwbuilder::CrawlerFind & cf)2676 ObjectDescriptor::ObjectDescriptor(const libfwbuilder::CrawlerFind& cf) {
2677     have_snmpd       = cf.have_snmpd;
2678     descr            = cf.descr;
2679     contact          = cf.contact;
2680     location         = cf.location;
2681     sysname          = cf.sysname;
2682     interfaces       = cf.interfaces;
2683     MAC_addr         = cf.found_phys_addr;
2684     dns_info.name    = cf.name;
2685     dns_info.aliases = cf.aliases;
2686 }
2687 #endif
2688 
~ObjectDescriptor()2689 ObjectDescriptor::~ObjectDescriptor()   {};
2690 
operator =(const ObjectDescriptor & od)2691 ObjectDescriptor& ObjectDescriptor::operator=(const ObjectDescriptor& od) {
2692     have_snmpd       = od.have_snmpd;
2693     descr            = od.descr;
2694     contact          = od.contact;
2695     location         = od.location;
2696     sysname          = od.sysname;
2697     interfaces       = od.interfaces;
2698     MAC_addr         = od.MAC_addr;
2699     dns_info.name    = od.dns_info.name;
2700     dns_info.aliases = od.dns_info.aliases;
2701     addr             = od.addr;
2702     type             = od.type;
2703     isSelected       = od.isSelected;
2704     netmask          = od.netmask;
2705 
2706     return *this;
2707 }
2708 
2709 // ================================================================
2710 
WorkerThread()2711 WorkerThread::WorkerThread() : QThread()
2712 {
2713     Log = new QueueLogger();
2714 }
2715 
~WorkerThread()2716 WorkerThread::~WorkerThread()
2717 {
2718     delete Log;
2719 }
2720 
setProgress(int p)2721 void WorkerThread::setProgress(int p)
2722 {
2723    ProgressEvent *event = new ProgressEvent();
2724    event->value=p;
2725 
2726    QApplication::postEvent(Widget,event);
2727 }
2728 
done()2729 void WorkerThread::done()
2730 {
2731    DoneEvent *event=new DoneEvent();
2732 
2733    QApplication::postEvent(Widget,event);
2734 }
2735 
getError()2736 QString WorkerThread::getError()
2737 {
2738     return last_error;
2739 }
2740 
run()2741 void WorkerThread::run()
2742 {
2743     done();
2744 }
2745 
2746 // ================================================================
2747 
HostsFileImport(const QString & f)2748 HostsFileImport::HostsFileImport(const QString &f) :
2749     WorkerThread()
2750 {
2751     file_name = f;
2752 }
2753 
run()2754 void HostsFileImport::run()
2755 {
2756     *Log << "Discovery method: "
2757          << "Read file in hosts format. \n";
2758 
2759     map<InetAddr, vector<string> > reverse_hosts;
2760     HostsFile *hf;
2761 /*
2762  *    read hosts file here
2763  */
2764     hf=new HostsFile();
2765     last_error="";
2766     setProgress(10);
2767 
2768     *Log << "Parsing file: " << file_name.toLatin1().constData() << "\n";
2769     if (!file_name.isEmpty())
2770     {
2771         try
2772         {
2773 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2774             hf->parse( file_name.toAscii().constData() );
2775 #else
2776             hf->parse( file_name.toLatin1().constData() );
2777 #endif
2778         } catch ( FWException &ex )
2779         {
2780             last_error = ex.toString().c_str();
2781 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
2782             *Log << "Exception: " << last_error.toAscii().constData() << "\n";
2783 #else
2784             *Log << "Exception: " << last_error.toLatin1().constData() << "\n";
2785 #endif
2786             delete hf;
2787             done();
2788             return;
2789         }
2790         reverse_hosts=hf->getAll();
2791         delete hf;
2792 
2793         setProgress(50);
2794         *Log << "Loading the list ...\n";
2795     /*
2796     *    convert map format
2797     */
2798         hosts.clear();
2799 
2800         map<InetAddr,vector<string> >::iterator i;
2801         int count=reverse_hosts.size();
2802         int t=0;
2803         for (i=reverse_hosts.begin(); i!=reverse_hosts.end(); ++i)
2804         {
2805 
2806             ObjectDescriptor od;
2807             od.addr    = (*i).first;
2808             od.sysname = ((*i).second).front();
2809 
2810             hosts.push_back( od );
2811 
2812             setProgress(50+(t++)*50/count);
2813         }
2814     }
2815     *Log << "done.\n";
2816     setProgress(100);
2817 
2818     done();
2819 }
2820 
2821 // ================================================================
2822 
ConfigImport(string * b,const std::string & p,const std::string & fwname)2823 ConfigImport::ConfigImport(string *b, const std::string &p, const std::string &fwname) : WorkerThread()
2824 {
2825     buffer = b;
2826     platform = p;
2827     this->fwname = fwname;
2828 }
2829 
~ConfigImport()2830 ConfigImport::~ConfigImport()
2831 {
2832     if (imp)  delete imp;
2833     if (buffer) delete buffer;
2834 }
2835 
run()2836 void ConfigImport::run()
2837 {
2838     *Log << "Discovery method: Import firewall configuration.\n";
2839 
2840     std::istringstream instream(*buffer);
2841 
2842     imp = NULL;
2843     if (platform == "iosacl") imp = new IOSImporter(mw->getCurrentLib(),
2844                                                     instream,
2845                                                     Log, fwname);
2846     if (platform == "iptables") imp = new IPTImporter(mw->getCurrentLib(),
2847                                                       instream,
2848                                                       Log, fwname);
2849     if (platform == "pix") imp = new PIXImporter(mw->getCurrentLib(),
2850                                                  instream,
2851                                                  Log, fwname);
2852 
2853     // add other platforms here when available
2854 
2855     if (imp)
2856     {
2857         try
2858         {
2859             imp->run();
2860         } catch(ImporterException &e)
2861         {
2862             last_error = e.toString().c_str();
2863             *Log << e.toString() << "\n";
2864         }
2865 
2866     } else
2867     {
2868         *Log << "Can not import configuration for choosen platform\n";
2869     }
2870 
2871     done();
2872 }
2873 
objNameChanged(QString)2874 void DiscoveryDruid::objNameChanged(QString)
2875 {
2876     m_dialog->nextButton->setEnabled(!(m_dialog->obj_name->text().isEmpty()
2877                                        || m_dialog->import_filename->text().isEmpty()));
2878     m_dialog->nextButton->setDefault(true);
2879 }
2880