From dd882b5d7ac96a6b9e023fa83dcb084ba61821bb Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Wed, 30 Aug 2017 21:20:31 +0500 Subject: [PATCH] Add FortSettings class. --- src/ui/FortFirewall.pro | 2 + src/ui/conf/firewallconf.cpp | 32 ++++-- src/ui/conf/firewallconf.h | 3 + src/ui/fortsettings.cpp | 187 +++++++++++++++++++++++++++++++++++ src/ui/fortsettings.h | 53 ++++++++++ src/ui/util/confutil.cpp | 15 +-- src/ui/util/confutil.h | 2 - src/ui/util/fileutil.cpp | 60 +++++++++++ src/ui/util/fileutil.h | 14 ++- 9 files changed, 341 insertions(+), 27 deletions(-) create mode 100644 src/ui/fortsettings.cpp create mode 100644 src/ui/fortsettings.h diff --git a/src/ui/FortFirewall.pro b/src/ui/FortFirewall.pro index c480df1d..61f89238 100644 --- a/src/ui/FortFirewall.pro +++ b/src/ui/FortFirewall.pro @@ -14,6 +14,7 @@ SOURCES += \ firewallLog/logbuffer.cpp \ firewallLog/logentry.cpp \ fortcommon.cpp \ + fortsettings.cpp \ util/confutil.cpp \ util/device.cpp \ util/fileutil.cpp \ @@ -27,6 +28,7 @@ HEADERS += \ firewallLog/logbuffer.h \ firewallLog/logentry.h \ fortcommon.h \ + fortsettings.h \ util/confutil.h \ util/device.h \ util/fileutil.h \ diff --git a/src/ui/conf/firewallconf.cpp b/src/ui/conf/firewallconf.cpp index c88d4161..0d7d64a0 100644 --- a/src/ui/conf/firewallconf.cpp +++ b/src/ui/conf/firewallconf.cpp @@ -61,6 +61,28 @@ void FirewallConf::setAppAllowAll(bool appAllowAll) } } +quint32 FirewallConf::appGroupBits() const +{ + quint32 groupBits = 0; + int i = 0; + foreach (const AppGroup *appGroup, appGroupsList()) { + if (appGroup->enabled()) { + groupBits |= (1 << i); + } + ++i; + } + return groupBits; +} + +void FirewallConf::setAppGroupBits(quint32 groupBits) +{ + int i = 0; + foreach (AppGroup *appGroup, appGroupsList()) { + appGroup->setEnabled(groupBits & (1 << i)); + ++i; + } +} + void FirewallConf::setIpIncludeText(const QString &ipIncludeText) { if (m_ipIncludeText != ipIncludeText) { @@ -113,11 +135,6 @@ QVariant FirewallConf::toVariant() const { QVariantMap map; - //map["filterDisabled"] = filterDisabled(); - map["ipIncludeAll"] = ipIncludeAll(); - map["ipExcludeAll"] = ipExcludeAll(); - map["appLogBlocked"] = appLogBlocked(); - map["appBlockAll"] = appBlockAll(); map["ipIncludeText"] = ipIncludeText(); map["ipExcludeText"] = ipExcludeText(); @@ -134,11 +151,6 @@ void FirewallConf::fromVariant(const QVariant &v) { QVariantMap map = v.toMap(); - //m_filterDisabled = map["filterDisabled"].toBool(); - m_ipIncludeAll = map["ipIncludeAll"].toBool(); - m_ipExcludeAll = map["ipExcludeAll"].toBool(); - m_appLogBlocked = map["appLogBlocked"].toBool(); - m_appBlockAll = map["appBlockAll"].toBool(); m_ipIncludeText = map["ipIncludeText"].toString(); m_ipExcludeText = map["ipExcludeText"].toString(); diff --git a/src/ui/conf/firewallconf.h b/src/ui/conf/firewallconf.h index 207ab3da..e6e09f03 100644 --- a/src/ui/conf/firewallconf.h +++ b/src/ui/conf/firewallconf.h @@ -42,6 +42,9 @@ public: bool appAllowAll() const { return m_appAllowAll; } void setAppAllowAll(bool appAllowAll); + quint32 appGroupBits() const; + void setAppGroupBits(quint32 groupBits); + QString ipIncludeText() const { return m_ipIncludeText; } void setIpIncludeText(const QString &ipIncludeText); diff --git a/src/ui/fortsettings.cpp b/src/ui/fortsettings.cpp new file mode 100644 index 00000000..8f9188e8 --- /dev/null +++ b/src/ui/fortsettings.cpp @@ -0,0 +1,187 @@ +#include "fortsettings.h" + +#include +#include +#include +#include + +#include "conf/firewallconf.h" +#include "util/fileutil.h" + +FortSettings::FortSettings(const QStringList &args, + QObject *parent) : + QObject(parent) +{ + processArguments(args); + setupIni(); +} + +void FortSettings::processArguments(const QStringList &args) +{ + const QCommandLineOption profileOption("profile", "Directory to store settings."); + + QCommandLineParser parser; + parser.addOption(profileOption); + parser.process(args); + + m_profilePath = parser.value(profileOption); + if (m_profilePath.isEmpty()) { + m_profilePath = QStandardPaths::writableLocation( + QStandardPaths::AppConfigLocation); + } + m_profilePath = FileUtil::absolutePath(m_profilePath); + + const QLatin1Char slash('/'); + if (!m_profilePath.endsWith(slash)) + m_profilePath += slash; +} + +void FortSettings::setupIni() +{ + const QString qrcIniPath(":/FortFirewall.ini"); + const QString iniPath(m_profilePath + "FortFirewall.ini"); + + FileUtil::makePath(m_profilePath); + + // Copy default .ini into writable location + if (!FileUtil::fileExists(iniPath)) { + const QString text = FileUtil::readFile(qrcIniPath); + if (!FileUtil::writeFile(iniPath, text)) { + FileUtil::removeFile(iniPath); + } + } + + m_ini = new QSettings(iniPath, QSettings::IniFormat, this); +} + +QString FortSettings::confFilePath() const +{ + return m_profilePath + QLatin1String("FortFirewall.conf"); +} + +QString FortSettings::confBackupFilePath() const +{ + return confFilePath() + QLatin1String(".backup"); +} + +bool FortSettings::readConf(FirewallConf &conf) const +{ + const QString filePath = confFilePath(); + const QString backupFilePath = confBackupFilePath(); + + return tryToReadConf(conf, filePath) + || tryToReadConf(conf, backupFilePath); +} + +bool FortSettings::tryToReadConf(FirewallConf &conf, const QString &filePath) const +{ + const QString text = FileUtil::readFile(filePath); + + QJsonParseError jsonParseError; + const QJsonDocument jsonDoc = QJsonDocument::fromJson( + text.toUtf8(), &jsonParseError); + if (jsonParseError.error != QJsonParseError::NoError) + return false; + + conf.fromVariant(jsonDoc.toVariant()); + + return readConfFlags(conf); +} + +bool FortSettings::writeConf(const FirewallConf &conf) +{ + const QString filePath = confFilePath(); + const QString backupFilePath = confBackupFilePath(); + + if (FileUtil::fileExists(backupFilePath) + && !FileUtil::renameFile(backupFilePath, filePath)) + return false; + + return tryToWriteConf(conf, backupFilePath) + && FileUtil::renameFile(backupFilePath, filePath); +} + +bool FortSettings::tryToWriteConf(const FirewallConf &conf, const QString &filePath) +{ + const QJsonDocument jsonDoc = QJsonDocument::fromVariant( + conf.toVariant()); + + const QByteArray data = jsonDoc.toJson(QJsonDocument::Indented); + + if (FileUtil::writeFileData(filePath, data)) + return false; + + return writeConfFlags(conf); +} + +bool FortSettings::readConfFlags(FirewallConf &conf) const +{ + conf.setFilterDisabled(iniBool("filterDisabled")); + conf.setIpIncludeAll(iniBool("ipIncludeAll")); + conf.setIpExcludeAll(iniBool("ipExcludeAll")); + conf.setAppLogBlocked(iniBool("appLogBlocked", true)); + conf.setAppBlockAll(iniBool("appBlockAll", true)); + conf.setAppAllowAll(iniBool("appAllowAll")); + conf.setAppGroupBits(iniUInt("appGroupBits", 0xFFFF)); + + return true; +} + +bool FortSettings::writeConfFlags(const FirewallConf &conf) +{ + setIniValue("filterDisabled", conf.filterDisabled()); + setIniValue("ipIncludeAll", conf.ipIncludeAll()); + setIniValue("ipExcludeAll", conf.ipExcludeAll()); + setIniValue("appLogBlocked", conf.appLogBlocked()); + setIniValue("appBlockAll", conf.appBlockAll()); + setIniValue("appAllowAll", conf.appAllowAll()); + setIniValue("appGroupBits", conf.appGroupBits()); + + m_ini->sync(); + + return m_ini->status() != QSettings::NoError; +} + +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(); +} + +int FortSettings::iniUInt(const QString &key, int defaultValue) const +{ + return iniValue(key, defaultValue).toUInt(); +} + +int FortSettings::iniReal(const QString &key, qreal defaultValue) const +{ + 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); +} + +void FortSettings::setIniValue(const QString &key, const QVariant &value) +{ + m_ini->setValue(key, value); +} diff --git a/src/ui/fortsettings.h b/src/ui/fortsettings.h new file mode 100644 index 00000000..5d90d906 --- /dev/null +++ b/src/ui/fortsettings.h @@ -0,0 +1,53 @@ +#ifndef FORTSETTINGS_H +#define FORTSETTINGS_H + +#include +#include + +class FirewallConf; + +class FortSettings : public QObject +{ + Q_OBJECT + +public: + explicit FortSettings(const QStringList &args, + QObject *parent = nullptr); + +signals: + +public slots: + QString confFilePath() const; + QString confBackupFilePath() const; + + bool readConf(FirewallConf &conf) const; + bool writeConf(const FirewallConf &conf); + + bool readConfFlags(FirewallConf &conf) const; + bool writeConfFlags(const FirewallConf &conf); + +private: + void processArguments(const QStringList &args); + void setupIni(); + + bool tryToReadConf(FirewallConf &conf, const QString &filePath) const; + bool tryToWriteConf(const FirewallConf &conf, const QString &filePath); + + bool iniBool(const QString &key, bool defaultValue = false) const; + int iniInt(const QString &key, int defaultValue = 0) const; + int iniUInt(const QString &key, int defaultValue = 0) const; + int iniReal(const QString &key, qreal defaultValue = 0) const; + QString iniText(const QString &key, const QString &defaultValue = QString()) const; + QStringList iniList(const QString &key) const; + + QVariant iniValue(const QString &key, + const QVariant &defaultValue = QVariant()) const; + void setIniValue(const QString &key, const QVariant &value); + +private: + QString m_profilePath; + + QSettings *m_ini; +}; + +#endif // FORTSETTINGS_H diff --git a/src/ui/util/confutil.cpp b/src/ui/util/confutil.cpp index dc6149fb..0cf04e5a 100644 --- a/src/ui/util/confutil.cpp +++ b/src/ui/util/confutil.cpp @@ -231,7 +231,7 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf, drvConf->flags.app_block_all = conf.appBlockAll(); drvConf->flags.app_allow_all = conf.appAllowAll(); - drvConf->flags.group_bits = appGroupBits(conf); + drvConf->flags.group_bits = conf.appGroupBits(); FortCommon::confAppPermsMaskInit(drvConf); @@ -284,16 +284,3 @@ void ConfUtil::writeStrings(char **data, const QStringList &list) *data += offTableSize + FORT_CONF_STR_DATA_SIZE(off); } - -quint32 ConfUtil::appGroupBits(const FirewallConf &conf) -{ - quint32 groupBits = 0; - int i = 0; - foreach (const AppGroup *appGroup, conf.appGroupsList()) { - if (appGroup->enabled()) { - groupBits |= (1 << i); - } - ++i; - } - return groupBits; -} diff --git a/src/ui/util/confutil.h b/src/ui/util/confutil.h index 1ddcf66b..aa12c6d3 100644 --- a/src/ui/util/confutil.h +++ b/src/ui/util/confutil.h @@ -53,8 +53,6 @@ private: static void writeNumbers(char **data, const QVector &array); static void writeStrings(char **data, const QStringList &list); - static quint32 appGroupBits(const FirewallConf &conf); - private: QString m_errorMessage; }; diff --git a/src/ui/util/fileutil.cpp b/src/ui/util/fileutil.cpp index a79c7e69..bc37b00c 100644 --- a/src/ui/util/fileutil.cpp +++ b/src/ui/util/fileutil.cpp @@ -1,6 +1,8 @@ #include "fileutil.h" #include +#include +#include #define WIN32_LEAN_AND_MEAN #include @@ -68,3 +70,61 @@ QString FileUtil::pathToDosPath(const QString &path) } return path; } + +QString FileUtil::absolutePath(const QString &path) +{ + return QDir(path).absolutePath(); +} + +bool FileUtil::makePath(const QString &path) +{ + return QDir().mkpath(path); +} + +bool FileUtil::fileExists(const QString &filePath) +{ + return QFileInfo::exists(filePath); +} + +bool FileUtil::removeFile(const QString &filePath) +{ + return QFile::remove(filePath); +} + +bool FileUtil::renameFile(const QString &oldFilePath, const QString &newFilePath) +{ + removeFile(newFilePath); + + return QFile::rename(oldFilePath, newFilePath); +} + +bool FileUtil::copyFile(const QString &filePath, const QString &newFilePath) +{ + return QFile::copy(filePath, newFilePath); +} + +QString FileUtil::readFile(const QString &filePath) +{ + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) + return QString(); + + QTextStream in(&file); + const QString data = in.readAll(); + return data; +} + +bool FileUtil::writeFile(const QString &filePath, const QString &text) +{ + return writeFileData(filePath, text.toUtf8()); +} + +bool FileUtil::writeFileData(const QString &filePath, const QByteArray &data) +{ + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + return false; + + return file.write(data) == data.size() + && file.flush(); +} diff --git a/src/ui/util/fileutil.h b/src/ui/util/fileutil.h index bd201229..e6e5767d 100644 --- a/src/ui/util/fileutil.h +++ b/src/ui/util/fileutil.h @@ -2,7 +2,6 @@ #define FILEUTIL_H #include -#include class FileUtil : public QObject { @@ -22,6 +21,19 @@ public: // Convert Win32 path to Native path static QString pathToDosPath(const QString &path); + + static QString absolutePath(const QString &path); + + static bool makePath(const QString &path); + static bool fileExists(const QString &filePath); + static bool removeFile(const QString &filePath); + static bool renameFile(const QString &oldFilePath, const QString &newFilePath); + static bool copyFile(const QString &filePath, const QString &newFilePath); + + static QString readFile(const QString &filePath); + + static bool writeFile(const QString &filePath, const QString &text); + static bool writeFileData(const QString &filePath, const QByteArray &data); }; #endif // FILEUTIL_H