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