fort/src/ui/fortsettings.cpp

402 lines
11 KiB
C++
Raw Normal View History

2017-08-30 16:20:31 +00:00
#include "fortsettings.h"
#include <QCommandLineParser>
2018-02-23 09:53:04 +00:00
#include <QCoreApplication>
2017-08-30 16:20:31 +00:00
#include <QJsonDocument>
#include <QSettings>
2017-09-02 10:17:51 +00:00
#include "conf/addressgroup.h"
2017-08-30 16:20:31 +00:00
#include "conf/firewallconf.h"
#include "util/fileutil.h"
FortSettings::FortSettings(const QStringList &args,
QObject *parent) :
QObject(parent),
m_hasProvBoot(false)
2017-08-30 16:20:31 +00:00
{
processArguments(args);
setupIni();
}
bool FortSettings::startWithWindows() const
{
return FileUtil::fileExists(startupShortcutPath());
}
void FortSettings::setStartWithWindows(bool start)
{
2017-12-23 05:48:04 +00:00
if (start == startWithWindows())
return;
const QString linkPath = startupShortcutPath();
if (start) {
FileUtil::linkFile(qApp->applicationFilePath(), linkPath);
} else {
FileUtil::removeFile(linkPath);
}
emit startWithWindowsChanged();
}
2017-08-30 16:20:31 +00:00
void FortSettings::processArguments(const QStringList &args)
{
QCommandLineParser parser;
2017-09-03 09:20:37 +00:00
const QCommandLineOption provBootOption(
QStringList() << "b" << "boot",
"Unblock access to network when Fort Firewall is not running.", "boot");
parser.addOption(provBootOption);
2017-09-03 09:20:37 +00:00
const QCommandLineOption profileOption(
QStringList() << "p" << "profile",
"Directory to store settings.", "profile");
2017-08-30 16:20:31 +00:00
parser.addOption(profileOption);
2017-09-03 09:20:37 +00:00
2017-09-03 10:16:51 +00:00
parser.addVersionOption();
parser.addHelpOption();
2017-08-30 16:20:31 +00:00
parser.process(args);
m_hasProvBoot = parser.isSet(provBootOption);
2017-09-03 09:20:37 +00:00
2017-08-30 16:20:31 +00:00
m_profilePath = parser.value(profileOption);
if (m_profilePath.isEmpty()) {
2017-09-03 06:49:58 +00:00
m_profilePath = FileUtil::appConfigLocation();
2017-08-30 16:20:31 +00:00
}
m_profilePath = FileUtil::absolutePath(m_profilePath);
const QLatin1Char slash('/');
2017-09-03 09:20:37 +00:00
if (!m_profilePath.endsWith(slash)) {
2017-08-30 16:20:31 +00:00
m_profilePath += slash;
2017-09-03 09:20:37 +00:00
}
2017-08-30 16:20:31 +00:00
}
void FortSettings::setupIni()
{
const QString iniPath(m_profilePath + "FortFirewall.ini");
FileUtil::makePath(m_profilePath);
m_ini = new QSettings(iniPath, QSettings::IniFormat, this);
}
2017-09-03 19:41:03 +00:00
void FortSettings::setErrorMessage(const QString &errorMessage)
{
if (m_errorMessage != errorMessage) {
m_errorMessage = errorMessage;
emit errorMessageChanged();
}
}
2017-09-20 15:43:43 +00:00
TasksMap FortSettings::tasks() const
{
TasksMap map;
const QString tasksPrefix("tasks");
foreach (const QString &taskName, iniChildKeys(tasksPrefix)) {
const QString taskKey(tasksPrefix + '/' + taskName);
map.insert(taskName, iniValue(taskKey).toByteArray());
}
return map;
}
bool FortSettings::setTasks(const TasksMap &map)
{
const QString tasksPrefix("tasks");
removeIniKey(tasksPrefix);
foreach (const QString &taskName, map.keys()) {
const QString taskKey(tasksPrefix + '/' + taskName);
setIniValue(taskKey, map.value(taskName));
}
return iniSync();
}
QString FortSettings::logsPath() const
{
return m_profilePath + QLatin1String("logs/");
}
2017-12-01 14:13:06 +00:00
QString FortSettings::statFilePath() const
{
return m_profilePath + QLatin1String("FortFirewall.stat");
}
2017-08-30 16:20:31 +00:00
QString FortSettings::confFilePath() const
{
return m_profilePath + QLatin1String("FortFirewall.conf");
}
QString FortSettings::confBackupFilePath() const
{
return confFilePath() + QLatin1String(".backup");
}
2018-01-09 08:25:51 +00:00
bool FortSettings::readConf(FirewallConf &conf, bool &isNew)
2017-08-30 16:20:31 +00:00
{
const QString filePath = confFilePath();
const QString backupFilePath = confBackupFilePath();
const bool fileExists = FileUtil::fileExists(filePath);
const bool backupFileExists = FileUtil::fileExists(backupFilePath);
2018-01-09 08:25:51 +00:00
isNew = !(fileExists || backupFileExists);
return (isNew || (fileExists && tryToReadConf(conf, filePath))
2017-11-01 03:30:17 +00:00
|| tryToReadConf(conf, backupFilePath))
2017-12-11 06:05:49 +00:00
&& readConfIni(conf); // read flags at the end to use correct app groups
2017-08-30 16:20:31 +00:00
}
2017-09-03 19:41:03 +00:00
bool FortSettings::tryToReadConf(FirewallConf &conf, const QString &filePath)
2017-08-30 16:20:31 +00:00
{
2017-09-02 12:29:07 +00:00
const QByteArray data = FileUtil::readFileData(filePath);
2017-08-30 16:20:31 +00:00
QJsonParseError jsonParseError;
const QJsonDocument jsonDoc = QJsonDocument::fromJson(
2017-09-02 12:29:07 +00:00
data, &jsonParseError);
2017-09-03 19:41:03 +00:00
if (jsonParseError.error != QJsonParseError::NoError) {
setErrorMessage(jsonParseError.errorString());
2017-08-30 16:20:31 +00:00
return false;
2017-09-03 19:41:03 +00:00
}
2017-08-30 16:20:31 +00:00
QVariant confVar = jsonDoc.toVariant();
confVar = migrateConf(confVar);
conf.fromVariant(confVar);
2017-08-30 16:20:31 +00:00
return true;
2017-08-30 16:20:31 +00:00
}
bool FortSettings::writeConf(const FirewallConf &conf)
{
const QString filePath = confFilePath();
const QString backupFilePath = confBackupFilePath();
2017-12-11 06:05:49 +00:00
if (!writeConfIni(conf)) {
setErrorMessage(tr("Can't write .ini file"));
return false;
}
2017-09-11 06:16:51 +00:00
if (!tryToWriteConf(conf, backupFilePath)) {
setErrorMessage(tr("Can't create backup .conf file"));
2017-09-03 19:41:03 +00:00
return false;
2017-09-11 06:16:51 +00:00
}
2017-09-03 19:41:03 +00:00
2018-02-16 12:55:42 +00:00
if (!(FileUtil::removeFile(filePath)
&& FileUtil::copyFile(backupFilePath, filePath))) {
setErrorMessage(tr("Can't create .conf file"));
2017-08-30 16:20:31 +00:00
return false;
2017-09-03 19:41:03 +00:00
}
2017-08-30 16:20:31 +00:00
2017-09-03 19:41:03 +00:00
return true;
2017-08-30 16:20:31 +00:00
}
bool FortSettings::tryToWriteConf(const FirewallConf &conf, const QString &filePath)
{
const QJsonDocument jsonDoc = QJsonDocument::fromVariant(
conf.toVariant());
const QByteArray data = jsonDoc.toJson(QJsonDocument::Indented);
2017-09-03 19:41:03 +00:00
if (!FileUtil::writeFileData(filePath, data)) {
setErrorMessage(tr("Can't write .conf file"));
2017-08-30 16:20:31 +00:00
return false;
2017-09-03 19:41:03 +00:00
}
2017-08-30 16:20:31 +00:00
return true;
2017-08-30 16:20:31 +00:00
}
2017-12-11 06:05:49 +00:00
bool FortSettings::readConfIni(FirewallConf &conf) const
2017-08-30 16:20:31 +00:00
{
2017-08-30 16:31:52 +00:00
m_ini->beginGroup("confFlags");
2017-10-28 01:57:44 +00:00
conf.setProvBoot(iniBool("provBoot"));
conf.setFilterEnabled(iniBool("filterEnabled", true));
2017-12-23 06:15:36 +00:00
conf.setStopTraffic(iniBool("stopTraffic"));
conf.setStopInetTraffic(iniBool("stopInetTraffic"));
conf.setIgnoreTcpRst(iniBool("ignoreTcpRst"));
2017-11-20 14:39:57 +00:00
conf.setResolveAddress(iniBool("resolveAddress"));
conf.setLogBlocked(iniBool("logBlocked"));
2017-11-03 04:18:37 +00:00
conf.setLogStat(iniBool("logStat"));
2017-08-30 16:20:31 +00:00
conf.setAppBlockAll(iniBool("appBlockAll", true));
conf.setAppAllowAll(iniBool("appAllowAll"));
2017-12-11 06:05:49 +00:00
conf.setAppGroupBits(iniUInt("appGroupBits", DEFAULT_APP_GROUP_BITS));
m_ini->endGroup();
m_ini->beginGroup("stat");
conf.setMonthStart(iniInt("monthStart", DEFAULT_MONTH_START));
2017-12-11 06:05:49 +00:00
conf.setTrafHourKeepDays(iniInt("trafHourKeepDays", DEFAULT_TRAF_HOUR_KEEP_DAYS));
conf.setTrafDayKeepDays(iniInt("trafDayKeepDays", DEFAULT_TRAF_DAY_KEEP_DAYS));
conf.setTrafMonthKeepMonths(iniInt("trafMonthKeepMonths", DEFAULT_TRAF_MONTH_KEEP_MONTHS));
conf.setTrafUnit(iniInt("trafUnit"));
2017-08-30 16:31:52 +00:00
m_ini->endGroup();
2017-08-30 16:20:31 +00:00
m_ini->beginGroup("quota");
conf.setQuotaDayMb(iniUInt("quotaDayMb"));
conf.setQuotaMonthMb(iniUInt("quotaMonthMb"));
m_ini->endGroup();
2017-08-30 16:20:31 +00:00
return true;
}
2017-12-11 06:05:49 +00:00
bool FortSettings::writeConfIni(const FirewallConf &conf)
2017-08-30 16:20:31 +00:00
{
2017-08-30 16:31:52 +00:00
m_ini->beginGroup("confFlags");
setIniValue("provBoot", conf.provBoot());
setIniValue("filterEnabled", conf.filterEnabled());
2017-12-23 06:15:36 +00:00
setIniValue("stopTraffic", conf.stopTraffic());
setIniValue("stopInetTraffic", conf.stopInetTraffic());
setIniValue("ignoreTcpRst", conf.ignoreTcpRst());
2017-11-20 14:39:57 +00:00
setIniValue("resolveAddress", conf.resolveAddress());
setIniValue("logBlocked", conf.logBlocked());
2017-11-03 04:18:37 +00:00
setIniValue("logStat", conf.logStat());
2017-08-30 16:20:31 +00:00
setIniValue("appBlockAll", conf.appBlockAll());
setIniValue("appAllowAll", conf.appAllowAll());
2017-12-11 06:05:49 +00:00
setIniValue("appGroupBits", conf.appGroupBits(), DEFAULT_APP_GROUP_BITS);
m_ini->endGroup();
m_ini->beginGroup("stat");
setIniValue("monthStart", conf.monthStart(), DEFAULT_MONTH_START);
2017-12-11 06:05:49 +00:00
setIniValue("trafHourKeepDays", conf.trafHourKeepDays(), DEFAULT_TRAF_HOUR_KEEP_DAYS);
setIniValue("trafDayKeepDays", conf.trafDayKeepDays(), DEFAULT_TRAF_DAY_KEEP_DAYS);
setIniValue("trafMonthKeepMonths", conf.trafMonthKeepMonths(), DEFAULT_TRAF_MONTH_KEEP_MONTHS);
setIniValue("trafUnit", conf.trafUnit());
2017-08-30 16:31:52 +00:00
m_ini->endGroup();
2017-08-30 16:20:31 +00:00
m_ini->beginGroup("quota");
setIniValue("quotaDayMb", conf.quotaDayMb());
setIniValue("quotaMonthMb", conf.quotaMonthMb());
m_ini->endGroup();
2018-01-30 08:11:49 +00:00
removeMigratedKeys();
2017-09-20 15:43:43 +00:00
return iniSync();
2017-08-30 16:20:31 +00:00
}
QVariant FortSettings::migrateConf(const QVariant &confVar)
{
const int version = iniVersion();
if (version == APP_VERSION)
return confVar;
QVariantMap map = confVar.toMap();
2018-03-05 12:17:13 +00:00
// COMPAT: v1.7.0: AddressGroups
if (version < 0x010700) {
const QVariantMap oldIncMap = map["ipInclude"].toMap();
const QVariantMap oldExcMap = map["ipExclude"].toMap();
QVariantMap inetMap;
inetMap["includeAll"] = iniBool("confFlags/ipIncludeAll");
inetMap["excludeAll"] = iniBool("confFlags/ipExcludeAll");
inetMap["includeText"] = oldIncMap["text"];
inetMap["excludeText"] = oldExcMap["text"];
QVariantList addrList;
addrList.append(inetMap);
map["addressGroups"] = addrList;
}
return map;
}
void FortSettings::removeMigratedKeys()
{
const int version = iniVersion();
if (version == APP_VERSION)
return;
setIniVersion(APP_VERSION);
2018-03-05 12:17:13 +00:00
// COMPAT: v1.7.0: AddressGroups
if (version < 0x010700) {
removeIniKey("confFlags/ipIncludeAll");
removeIniKey("confFlags/ipExcludeAll");
}
2018-03-05 12:17:13 +00:00
// COMPAT: v1.10.0: Log Errors
2018-01-30 08:11:49 +00:00
if (version < 0x011000) {
removeIniKey("confFlags/logErrors");
}
}
2017-08-30 16:20:31 +00:00
bool FortSettings::iniBool(const QString &key, bool defaultValue) const
{
return iniValue(key, defaultValue).toBool();
}
int FortSettings::iniInt(const QString &key, int defaultValue) const
{
return iniValue(key, defaultValue).toInt();
}
2017-12-11 06:05:49 +00:00
uint FortSettings::iniUInt(const QString &key, int defaultValue) const
2017-08-30 16:20:31 +00:00
{
return iniValue(key, defaultValue).toUInt();
}
2017-12-14 08:44:10 +00:00
qreal FortSettings::iniReal(const QString &key, qreal defaultValue) const
2017-08-30 16:20:31 +00:00
{
return iniValue(key, defaultValue).toReal();
}
QString FortSettings::iniText(const QString &key, const QString &defaultValue) const
{
return iniValue(key, defaultValue).toString();
}
QStringList FortSettings::iniList(const QString &key) const
{
return iniValue(key).toStringList();
}
QVariant FortSettings::iniValue(const QString &key,
const QVariant &defaultValue) const
{
if (key.isEmpty())
return QVariant();
return m_ini->value(key, defaultValue);
}
2017-08-30 16:31:52 +00:00
void FortSettings::setIniValue(const QString &key, const QVariant &value,
const QVariant &defaultValue)
2017-08-30 16:20:31 +00:00
{
2017-08-30 16:31:52 +00:00
if (m_ini->value(key, defaultValue) == value)
return;
2017-08-30 16:20:31 +00:00
m_ini->setValue(key, value);
2017-08-30 16:31:52 +00:00
emit iniChanged();
2017-08-30 16:20:31 +00:00
}
2017-09-20 15:43:43 +00:00
void FortSettings::removeIniKey(const QString &key)
{
m_ini->remove(key);
}
QStringList FortSettings::iniChildKeys(const QString &prefix) const
{
m_ini->beginGroup(prefix);
const QStringList list = m_ini->childKeys();
m_ini->endGroup();
return list;
}
bool FortSettings::iniSync()
{
m_ini->sync();
return m_ini->status() == QSettings::NoError;
}
QString FortSettings::startupShortcutPath()
{
return FileUtil::applicationsLocation() + QLatin1Char('\\')
+ "Startup" + QLatin1Char('\\')
+ qApp->applicationName() + ".lnk";
}