1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-06-24 01:49:36 +02:00
Files
fwbuilder/src/libgui/secuwallosAdvancedDialog.cpp
2019-07-22 17:08:51 +00:00

487 lines
15 KiB
C++

/*
* secuwallosAdvancedDialog.cpp - secuwall advanced host OS dialog implementation
*
* Copyright (c) 2008 secunet Security Networks AG
* Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger@swiss-it.ch>
* Copyright (c) 2008 Reto Buerki <buerki@swiss-it.ch>
*
* This work is dual-licensed under:
*
* o The terms of the GNU General Public License as published by the Free
* Software Foundation, either version 2 of the License, or (at your option)
* any later version.
*
* o The terms of NetCitadel End User License Agreement
*/
#include "global.h"
#include "platforms.h"
#include <memory>
#include "secuwallosAdvancedDialog.h"
#include "FWCmdChange.h"
#include "fwbuilder/Firewall.h"
#include <qcheckbox.h>
#include <qspinbox.h>
#include <qcombobox.h>
#include <qradiobutton.h>
#include <qlineedit.h>
#include <qstackedwidget.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <qdesktopservices.h>
#include <qurl.h>
#include "FWWindow.h"
#include "Help.h"
using namespace std;
using namespace libfwbuilder;
secuwallosAdvancedDialog::~secuwallosAdvancedDialog()
{
delete m_dialog;
}
secuwallosAdvancedDialog::secuwallosAdvancedDialog(QWidget *parent, FWObject *o)
: QDialog(parent)
{
m_dialog = new Ui::secuwallosAdvancedDialog_q;
m_dialog->setupUi(this);
setWindowModality(Qt::WindowModal);
obj = o;
FWOptions *fwopt = (Firewall::cast(obj))->getOptionsObject();
assert(fwopt != nullptr);
// mappings from value to QComboBox index
QStringList threeStateMapping;
QStringList resoStateMapping;
threeStateMapping.push_back(QObject::tr("No change"));
threeStateMapping.push_back("");
threeStateMapping.push_back(QObject::tr("On"));
threeStateMapping.push_back("1");
threeStateMapping.push_back(QObject::tr("Off"));
threeStateMapping.push_back("0");
resoStateMapping.push_back("");
resoStateMapping.push_back("none");
resoStateMapping.push_back("Hosts");
resoStateMapping.push_back("files");
resoStateMapping.push_back("DNS");
resoStateMapping.push_back("dns");
resoStateMapping.push_back("NIS");
resoStateMapping.push_back("nis");
resoStateMapping.push_back("NIS+");
resoStateMapping.push_back("nisplus");
resoStateMapping.push_back("DB");
resoStateMapping.push_back("db");
// management settings
data.registerOption(m_dialog->secuwall_mgmt_mgmtaddr,
fwopt,
"secuwall_mgmt_mgmtaddr");
data.registerOption(m_dialog->secuwall_mgmt_loggingaddr,
fwopt,
"secuwall_mgmt_loggingaddr");
data.registerOption(m_dialog->secuwall_mgmt_snmpaddr,
fwopt,
"secuwall_mgmt_snmpaddr");
data.registerOption(m_dialog->secuwall_mgmt_rosnmp,
fwopt,
"secuwall_mgmt_rosnmp");
data.registerOption(m_dialog->secuwall_mgmt_ntpaddr,
fwopt,
"secuwall_mgmt_ntpaddr");
data.registerOption(m_dialog->secuwall_mgmt_nagiosaddr,
fwopt,
"secuwall_mgmt_nagiosaddr");
data.registerOption(m_dialog->secuwall_mgmt_varpart,
fwopt,
"secuwall_mgmt_varpart");
data.registerOption(m_dialog->secuwall_mgmt_confpart,
fwopt,
"secuwall_mgmt_confpart");
data.registerOption(m_dialog->secuwall_mgmt_rules_disable,
fwopt,
"secuwall_mgmt_rules_disable");
// dns settings
data.registerOption(m_dialog->secuwall_dns_srv1,
fwopt,
"secuwall_dns_srv1");
data.registerOption(m_dialog->secuwall_dns_srv2,
fwopt,
"secuwall_dns_srv2");
data.registerOption(m_dialog->secuwall_dns_srv3,
fwopt,
"secuwall_dns_srv3");
data.registerOption(m_dialog->secuwall_dns_domains,
fwopt,
"secuwall_dns_domains");
data.registerOption(m_dialog->secuwall_dns_reso1,
fwopt,
"secuwall_dns_reso1", resoStateMapping);
data.registerOption(m_dialog->secuwall_dns_reso2,
fwopt,
"secuwall_dns_reso2", resoStateMapping);
data.registerOption(m_dialog->secuwall_dns_reso3,
fwopt,
"secuwall_dns_reso3", resoStateMapping);
data.registerOption(m_dialog->secuwall_dns_reso4,
fwopt,
"secuwall_dns_reso4", resoStateMapping);
data.registerOption(m_dialog->secuwall_dns_reso5,
fwopt,
"secuwall_dns_reso5", resoStateMapping);
// hosts settings
data.registerOption(m_dialog->secuwall_dns_hosts,
fwopt,
"secuwall_dns_hosts", resoStateMapping);
// iptables / routing and TCP
data.registerOption(m_dialog->linux24_log_martians,
fwopt,
"linux24_log_martians", threeStateMapping);
data.registerOption(m_dialog->linux24_accept_redirects,
fwopt,
"linux24_accept_redirects", threeStateMapping);
data.registerOption(m_dialog->linux24_icmp_echo_ignore_all,
fwopt,
"linux24_icmp_echo_ignore_all", threeStateMapping);
data.registerOption(m_dialog->linux24_icmp_echo_ignore_broadcasts,
fwopt,
"linux24_icmp_echo_ignore_broadcasts",
threeStateMapping);
data.registerOption(m_dialog->linux24_icmp_ignore_bogus_error_responses,
fwopt,
"linux24_icmp_ignore_bogus_error_responses",
threeStateMapping);
data.registerOption(m_dialog->linux24_ip_dynaddr,
fwopt,
"linux24_ip_dynaddr", threeStateMapping);
data.registerOption(m_dialog->linux24_rp_filter,
fwopt,
"linux24_rp_filter", threeStateMapping);
data.registerOption(m_dialog->linux24_accept_source_route,
fwopt,
"linux24_accept_source_route", threeStateMapping);
data.registerOption(m_dialog->linux24_ip_forward,
fwopt,
"linux24_ip_forward", threeStateMapping);
data.registerOption(m_dialog->linux24_ipv6_forward,
fwopt,
"linux24_ipv6_forward", threeStateMapping);
data.registerOption(m_dialog->linux24_tcp_fin_timeout,
fwopt,
"linux24_tcp_fin_timeout");
data.registerOption(m_dialog->linux24_tcp_keepalive_interval,
fwopt,
"linux24_tcp_keepalive_interval");
data.registerOption(m_dialog->linux24_tcp_window_scaling,
fwopt,
"linux24_tcp_window_scaling", threeStateMapping);
data.registerOption(m_dialog->linux24_tcp_sack,
fwopt,
"linux24_tcp_sack", threeStateMapping);
data.registerOption(m_dialog->linux24_tcp_fack,
fwopt,
"linux24_tcp_fack", threeStateMapping);
data.registerOption(m_dialog->linux24_tcp_ecn,
fwopt,
"linux24_tcp_ecn", threeStateMapping);
data.registerOption(m_dialog->linux24_tcp_syncookies,
fwopt,
"linux24_tcp_syncookies", threeStateMapping);
data.registerOption(m_dialog->linux24_tcp_timestamps,
fwopt,
"linux24_tcp_timestamps", threeStateMapping);
// additional files
data.registerOption(m_dialog->additional_files_enabled,
fwopt,
"secuwall_add_files");
data.registerOption(m_dialog->additional_files_dir,
fwopt,
"secuwall_add_files_dir");
data.loadAll();
m_dialog->tabWidget->setCurrentIndex(0);
}
/*
* store all data in the object
*/
void secuwallosAdvancedDialog::accept()
{
// validate user input before saving
if (!validate()) return;
ProjectPanel *project = mw->activeProject();
std::unique_ptr<FWCmdChange> cmd( new FWCmdChange(project, obj));
// new_state is a copy of the fw object
FWObject* new_state = cmd->getNewState();
FWOptions* fwoptions = Firewall::cast(new_state)->getOptionsObject();
assert(fwoptions!=nullptr);
data.saveAll(fwoptions);
if (!cmd->getOldState()->cmp(new_state, true))
project->undoStack->push(cmd.release());
QDialog::accept();
}
void secuwallosAdvancedDialog::reject()
{
QDialog::reject();
}
void secuwallosAdvancedDialog::help()
{
QString tab_title = m_dialog->tabWidget->tabText(
m_dialog->tabWidget->currentIndex());
QString anchor = tab_title.replace('/', '-').replace(' ', '-').toLower();
Help *h = Help::getHelpWindow(this);
h->setName("Host secunet wall");
h->setSource(QUrl("secuwallosAdvancedDialog.html#" + anchor));
h->raise();
h->show();
}
void secuwallosAdvancedDialog::additionalChanged(int state)
{
if (state == Qt::Checked)
{
m_dialog->templdir_label->setEnabled(true);
m_dialog->additional_files_dir->setEnabled(true);
m_dialog->buttonBrowse->setEnabled(true);
m_dialog->buttonOpenURL->setEnabled(true);
}
else
{
m_dialog->templdir_label->setEnabled(false);
m_dialog->additional_files_dir->setEnabled(false);
m_dialog->buttonBrowse->setEnabled(false);
m_dialog->buttonOpenURL->setEnabled(false);
}
}
void secuwallosAdvancedDialog::buttonBrowseClicked()
{
QString templ_dir = QFileDialog::getExistingDirectory
(this,
tr("Select templates directory"),
m_dialog->additional_files_dir->text(),
QFileDialog::DontResolveSymlinks);
if (templ_dir == "")
{
return ;
}
m_dialog->additional_files_dir->setText(templ_dir);
}
void secuwallosAdvancedDialog::buttonOpenURLClicked()
{
bool ok = true;
QString message;
QString path = m_dialog->additional_files_dir->text();
QUrl url("file://" + path);
if (!url.isValid())
{
ok = false;
message = tr("URL is not valid: %1").arg(path);
}
else
{
// note: "Warning: unknown mime-type" errors can not be detected here
if (!QDesktopServices::openUrl(url))
{
ok = false;
message = tr("Could not open URL: %1").arg(url.toLocalFile());
}
}
if (!ok)
{
QMessageBox::warning
(this, "Firewall Builder",
message, "&Continue", QString(), QString(), 0, 1);
}
}
bool secuwallosAdvancedDialog::validate()
{
bool valid = true;
QWidget *focus = nullptr;
QString message;
// widgets to verify
struct _tocheck {
QLineEdit* widget;
bool (*chkfn)(const QString &);
} widgets[5] =
{
{
m_dialog->secuwall_mgmt_mgmtaddr,
&secuwallosAdvancedDialog::validateNetworkOrAddress
},
{
m_dialog->secuwall_mgmt_loggingaddr,
&secuwallosAdvancedDialog::validateAddress
},
{
m_dialog->secuwall_mgmt_snmpaddr,
&secuwallosAdvancedDialog::validateNetworkOrAddress
},
{
m_dialog->secuwall_mgmt_ntpaddr,
&secuwallosAdvancedDialog::validateAddress
},
{
m_dialog->secuwall_mgmt_nagiosaddr,
&secuwallosAdvancedDialog::validateNetworkOrAddress
},
};
int size = sizeof(widgets) / sizeof(struct _tocheck);
// reset widget colors first
for (int i = 0; i < size; i++)
{
if (widgets[i].widget->palette() != QApplication::palette())
{
widgets[i].widget->setPalette(QApplication::palette());
}
}
// validate each widget one by one
for (int i = 0; i < size && valid; i++)
{
// get text to verify
QString to_verify = widgets[i].widget->text();
// focus current widget
focus = widgets[i].widget;
// if empty, continue
if (to_verify.isEmpty())
{
continue;
}
// check comma sep. list of addresses
QStringList addrlist = to_verify.split(",");
int pos = 1;
foreach(QString addr, addrlist)
{
if (addr.isEmpty())
{
valid = false;
message = tr("Empty address found (position %1)").arg(pos);
break;
}
addr = addr.simplified();
if (!widgets[i].chkfn(addr))
{
valid = false;
message = tr("Illegal address '%1' (position %2)").
arg(addr).arg(pos);
break;
}
pos++;
}
}
if (!valid)
{
// highlight error: focus and set different background color
focus->setFocus();
m_dialog->tabWidget->setCurrentIndex(0);
QPalette palette;
palette.setColor(focus->backgroundRole(), QColor(255, 0, 0, 100));
focus->setPalette(palette);
// display errror message
QMessageBox::warning(this, "Firewall Builder",
tr("Input not valid: %1").arg(message), "&Continue",
QString(), QString(), 0, 1);
}
return valid;
}
bool secuwallosAdvancedDialog::validateAddress(const QString &addr)
{
if (addr.indexOf("/") != -1)
{
return false;
}
try
{
InetAddr(addr.toLatin1().constData());
} catch (FWException &ex)
{
return false;
}
return true;
}
bool secuwallosAdvancedDialog::validateNetwork(const QString &addr)
{
if (addr.indexOf("/") == -1)
{
return false;
}
// validate IP/netmask address pairs
QStringList addrpair = addr.split("/");
try
{
InetAddr(addrpair.at(0).toLatin1().constData());
} catch (FWException &ex)
{
return false;
}
try
{
InetAddr(addrpair.at(1).toLatin1().constData());
} catch (FWException &ex)
{
// not in dotted notation?
bool ok = false;
int ilen = addrpair[1].toInt(&ok);
if (ok)
{
if (ilen < 0 || ilen > 32)
{
return false;
}
}
else
{
return false;
}
}
return true;
}
bool secuwallosAdvancedDialog::validateNetworkOrAddress(const QString &addr)
{
return (validateNetwork(addr) || validateAddress(addr));
}