UI: ConfUtil: Prepare writeRules()

This commit is contained in:
Nodir Temirkhodjaev 2024-04-14 10:34:02 +03:00
parent 7a821c2bcc
commit f3248ac627
10 changed files with 187 additions and 22 deletions

View File

@ -148,7 +148,7 @@ typedef struct fort_conf_rule
typedef struct fort_conf_rules typedef struct fort_conf_rules
{ {
UINT32 rule_off[FORT_CONF_RULE_MAX]; UINT16 max_rule_id;
char data[4]; char data[4];
} FORT_CONF_RULES, *PFORT_CONF_RULES; } FORT_CONF_RULES, *PFORT_CONF_RULES;
@ -159,6 +159,7 @@ typedef struct fort_conf_rule_flag
UCHAR enabled; UCHAR enabled;
} FORT_CONF_RULE_FLAG, *PFORT_CONF_RULE_FLAG; } FORT_CONF_RULE_FLAG, *PFORT_CONF_RULE_FLAG;
#define FORT_CONF_RULES_DATA_OFF offsetof(FORT_CONF_RULES, data)
#define FORT_CONF_RULE_SIZE(rule) \ #define FORT_CONF_RULE_SIZE(rule) \
(sizeof(FORT_CONF_RULE) + ((rule)->has_zones ? sizeof(FORT_CONF_RULE_ZONES) : 0) \ (sizeof(FORT_CONF_RULE) + ((rule)->has_zones ? sizeof(FORT_CONF_RULE_ZONES) : 0) \
+ (rule)->set_count * sizeof(UINT16)) + (rule)->set_count * sizeof(UINT16))

View File

@ -397,6 +397,7 @@ HEADERS += \
util/conf/addressrange.h \ util/conf/addressrange.h \
util/conf/appparseoptions.h \ util/conf/appparseoptions.h \
util/conf/confappswalker.h \ util/conf/confappswalker.h \
util/conf/confruleswalker.h \
util/conf/confutil.h \ util/conf/confutil.h \
util/dateutil.h \ util/dateutil.h \
util/device.h \ util/device.h \

View File

@ -62,7 +62,8 @@ const char *const sqlSelectAppById = "SELECT" SELECT_APP_FIELDS " FROM app t"
const char *const sqlSelectApps = "SELECT" SELECT_APP_FIELDS " FROM app t" const char *const sqlSelectApps = "SELECT" SELECT_APP_FIELDS " FROM app t"
" JOIN app_group g ON g.app_group_id = t.app_group_id" " JOIN app_group g ON g.app_group_id = t.app_group_id"
" LEFT JOIN app_alert alert ON alert.app_id = t.app_id;"; " LEFT JOIN app_alert alert ON alert.app_id = t.app_id"
" ORDER BY t.path;";
const char *const sqlSelectAppsToPurge = "SELECT app_id, path FROM app" const char *const sqlSelectAppsToPurge = "SELECT app_id, path FROM app"
" WHERE is_wildcard = 0 AND parked = 0;"; " WHERE is_wildcard = 0 AND parked = 0;";
@ -491,7 +492,7 @@ QVector<qint64> ConfAppManager::collectObsoleteApps(quint32 driveMask)
return appIdList; return appIdList;
} }
bool ConfAppManager::walkApps(const std::function<walkAppsCallback> &func) bool ConfAppManager::walkApps(const std::function<walkAppsCallback> &func) const
{ {
SqliteStmt stmt; SqliteStmt stmt;
if (!DbQuery(sqliteDb()).sql(sqlSelectApps).prepare(stmt)) if (!DbQuery(sqliteDb()).sql(sqlSelectApps).prepare(stmt))

View File

@ -43,7 +43,7 @@ public:
virtual bool updateAppsBlocked( virtual bool updateAppsBlocked(
const QVector<qint64> &appIdList, bool blocked, bool killProcess); const QVector<qint64> &appIdList, bool blocked, bool killProcess);
bool walkApps(const std::function<walkAppsCallback> &func) override; bool walkApps(const std::function<walkAppsCallback> &func) const override;
bool saveAppBlocked(const App &app); bool saveAppBlocked(const App &app);
void updateAppEndTimes(); void updateAppEndTimes();

View File

@ -18,6 +18,25 @@ namespace {
const QLoggingCategory LC("confRule"); const QLoggingCategory LC("confRule");
#define SELECT_RULE_FIELDS \
" t.rule_id," \
" t.enabled," \
" t.blocked," \
" t.exclusive," \
" t.rule_text," \
" t.rule_type," \
" t.accept_zones," \
" t.reject_zones"
const char *const sqlSelectRules = "SELECT" SELECT_RULE_FIELDS " FROM rule t"
" ORDER BY t.rule_id;";
const char *const sqlSelectRuleSets = "SELECT t.rule_id, t.sub_rule_id"
" FROM rule_set t"
" ORDER BY t.rule_id, t.order_index;";
const char *const sqlSelectMaxRuleId = "SELECT MAX(rule_id) FROM rule;";
const char *const sqlInsertRule = "INSERT INTO rule(rule_id, enabled, blocked, exclusive," const char *const sqlInsertRule = "INSERT INTO rule(rule_id, enabled, blocked, exclusive,"
" name, notes, rule_text, rule_type," " name, notes, rule_text, rule_type,"
" accept_zones, reject_zones, mod_time)" " accept_zones, reject_zones, mod_time)"
@ -191,8 +210,6 @@ bool ConfRuleManager::addOrUpdateRule(Rule &rule)
.sql(sqlSelectRuleIds) .sql(sqlSelectRuleIds)
.vars({ ConfUtil::ruleMaxCount() }) .vars({ ConfUtil::ruleMaxCount() })
.getFreeId(/*maxId=*/ConfUtil::ruleMaxCount() - 1); .getFreeId(/*maxId=*/ConfUtil::ruleMaxCount() - 1);
} else {
updateDriverRuleFlag(rule.ruleId, rule.enabled);
} }
const QVariantList vars = { const QVariantList vars = {
@ -220,6 +237,8 @@ bool ConfRuleManager::addOrUpdateRule(Rule &rule)
if (!ok) if (!ok)
return false; return false;
updateDriverRules();
if (isNew) { if (isNew) {
emit ruleAdded(); emit ruleAdded();
} else { } else {
@ -251,6 +270,8 @@ bool ConfRuleManager::deleteRule(int ruleId)
if (ok) { if (ok) {
emit ruleRemoved(ruleId); emit ruleRemoved(ruleId);
updateDriverRules();
} }
return ok; return ok;
@ -296,16 +317,97 @@ bool ConfRuleManager::updateRuleEnabled(int ruleId, bool enabled)
return ok; return ok;
} }
void ConfRuleManager::updateDriverRules(quint32 rulesMask, quint32 enabledMask, quint32 dataSize, bool ConfRuleManager::walkRules(ruleset_map_t &ruleSetMap, ruleid_arr_t &ruleIds, int &maxRuleId,
const QList<QByteArray> &rulesData) const std::function<walkRulesCallback> &func) const
{
bool ok = false;
sqliteDb()->beginTransaction();
maxRuleId = DbQuery(sqliteDb()).sql(sqlSelectMaxRuleId).execute().toInt();
walkRulesMap(ruleSetMap, ruleIds);
ok = walkRulesLoop(func);
sqliteDb()->commitTransaction();
return ok;
}
void ConfRuleManager::walkRulesMap(ruleset_map_t &ruleSetMap, ruleid_arr_t &ruleIds) const
{
SqliteStmt stmt;
if (!DbQuery(sqliteDb()).sql(sqlSelectRuleSets).prepare(stmt))
return;
int prevRuleId = 0;
int prevIndex = 0;
int index = 0;
for (;;) {
const bool isStepRow = (stmt.step() == SqliteStmt::StepRow);
const int ruleId = stmt.columnInt(0);
const int subRuleId = stmt.columnInt(1);
if (prevRuleId != ruleId) {
const RuleSetIndex ruleSetIndex = {
.index = quint32(prevIndex),
.count = quint8(index - prevIndex),
};
ruleSetMap.insert(prevRuleId, ruleSetIndex);
prevRuleId = ruleId;
prevIndex = index;
}
ruleIds.append(subRuleId);
++index;
if (!isStepRow)
break;
}
}
bool ConfRuleManager::walkRulesLoop(const std::function<walkRulesCallback> &func) const
{
SqliteStmt stmt;
if (!DbQuery(sqliteDb()).sql(sqlSelectRules).prepare(stmt))
return false;
while (stmt.step() == SqliteStmt::StepRow) {
Rule rule;
fillRule(rule, stmt);
if (!func(rule))
return false;
}
return true;
}
void ConfRuleManager::fillRule(Rule &rule, const SqliteStmt &stmt)
{
rule.ruleId = stmt.columnInt(0);
rule.enabled = stmt.columnBool(1);
rule.blocked = stmt.columnBool(2);
rule.exclusive = stmt.columnBool(3);
rule.ruleText = stmt.columnText(4);
rule.ruleType = Rule::RuleType(stmt.columnInt(5));
rule.acceptZones = stmt.columnUInt64(6);
rule.rejectZones = stmt.columnUInt64(7);
}
void ConfRuleManager::updateDriverRules()
{ {
ConfUtil confUtil; ConfUtil confUtil;
#if 0 confUtil.writeRules(*this);
const int entrySize = confUtil.writeRules(rulesMask, enabledMask, dataSize, rulesData);
driverWriteRules(confUtil, confUtil.buffer(), entrySize); // driverWriteRules(confUtil, confUtil.buffer(), entrySize);
#endif
} }
bool ConfRuleManager::updateDriverRuleFlag(int ruleId, bool enabled) bool ConfRuleManager::updateDriverRuleFlag(int ruleId, bool enabled)
@ -313,9 +415,9 @@ bool ConfRuleManager::updateDriverRuleFlag(int ruleId, bool enabled)
ConfUtil confUtil; ConfUtil confUtil;
#if 0 #if 0
const int entrySize = confUtil.writeRuleFlag(ruleId, enabled); confUtil.writeRuleFlag(ruleId, enabled);
return driverWriteRules(confUtil, confUtil.buffer(), entrySize, /*onlyFlags=*/true); return driverWriteRules(confUtil, confUtil.buffer(), /*onlyFlags=*/true);
#endif #endif
return true; return true;
} }

View File

@ -7,11 +7,12 @@
#include <conf/rule.h> #include <conf/rule.h>
#include <util/classhelpers.h> #include <util/classhelpers.h>
#include <util/conf/confruleswalker.h>
#include <util/ioc/iocservice.h> #include <util/ioc/iocservice.h>
class ConfManager; class ConfManager;
class ConfRuleManager : public QObject, public IocService class ConfRuleManager : public QObject, public ConfRulesWalker, public IocService
{ {
Q_OBJECT Q_OBJECT
@ -35,8 +36,10 @@ public:
virtual bool updateRuleName(int ruleId, const QString &ruleName); virtual bool updateRuleName(int ruleId, const QString &ruleName);
virtual bool updateRuleEnabled(int ruleId, bool enabled); virtual bool updateRuleEnabled(int ruleId, bool enabled);
void updateDriverRules(quint32 rulesMask, quint32 enabledMask, quint32 dataSize, bool walkRules(ruleset_map_t &ruleSetMap, ruleid_arr_t &ruleIds, int &maxRuleId,
const QList<QByteArray> &rulesData); const std::function<walkRulesCallback> &func) const override;
void updateDriverRules();
signals: signals:
void ruleAdded(); void ruleAdded();
@ -44,6 +47,11 @@ signals:
void ruleUpdated(); void ruleUpdated();
private: private:
void walkRulesMap(ruleset_map_t &ruleSetMap, ruleid_arr_t &ruleIds) const;
bool walkRulesLoop(const std::function<walkRulesCallback> &func) const;
static void fillRule(Rule &rule, const SqliteStmt &stmt);
bool updateDriverRuleFlag(int ruleId, bool enabled); bool updateDriverRuleFlag(int ruleId, bool enabled);
bool beginTransaction(); bool beginTransaction();

View File

@ -12,7 +12,7 @@ using walkAppsCallback = bool(App &app);
class ConfAppsWalker class ConfAppsWalker
{ {
public: public:
virtual bool walkApps(const std::function<walkAppsCallback> &func) = 0; virtual bool walkApps(const std::function<walkAppsCallback> &func) const = 0;
}; };
#endif // CONFAPPSWALKER_H #endif // CONFAPPSWALKER_H

View File

@ -0,0 +1,30 @@
#ifndef CONFRULESWALKER_H
#define CONFRULESWALKER_H
#include <QHash>
#include <QObject>
#include <QVector>
#include <functional>
#include <conf/rule.h>
struct RuleSetIndex
{
quint32 index : 24;
quint32 count : 8;
};
using ruleset_map_t = QHash<quint16, RuleSetIndex>;
using ruleid_arr_t = QVector<quint16>;
using walkRulesCallback = bool(Rule &rule);
class ConfRulesWalker
{
public:
virtual bool walkRules(ruleset_map_t &ruleSetMap, ruleid_arr_t &ruleIds, int &maxRuleId,
const std::function<walkRulesCallback> &func) const = 0;
};
#endif // CONFRULESWALKER_H

View File

@ -15,6 +15,7 @@
#include <util/stringutil.h> #include <util/stringutil.h>
#include "confappswalker.h" #include "confappswalker.h"
#include "confruleswalker.h"
#define APP_GROUP_MAX FORT_CONF_GROUP_MAX #define APP_GROUP_MAX FORT_CONF_GROUP_MAX
#define APP_GROUP_NAME_MAX 128 #define APP_GROUP_NAME_MAX 128
@ -218,7 +219,7 @@ void ConfUtil::writeServices(const QVector<ServiceInfo> &services, int runningSe
} }
bool ConfUtil::write( bool ConfUtil::write(
const FirewallConf &conf, ConfAppsWalker *confAppsWalker, EnvManager &envManager) const FirewallConf &conf, const ConfAppsWalker *confAppsWalker, EnvManager &envManager)
{ {
WriteConfArgs wca = { .conf = conf, WriteConfArgs wca = { .conf = conf,
.ad = { .addressRanges = addrranges_arr_t(conf.addressGroups().size()) } }; .ad = { .addressRanges = addrranges_arr_t(conf.addressGroups().size()) } };
@ -287,6 +288,22 @@ bool ConfUtil::writeAppEntry(const App &app, bool isNew)
return true; return true;
} }
bool ConfUtil::writeRules(const ConfRulesWalker &confRulesWalker)
{
ruleset_map_t ruleSetMap;
ruleid_arr_t ruleIds;
int maxRuleId;
return confRulesWalker.walkRules(ruleSetMap, ruleIds, maxRuleId, [&](Rule &rule) -> bool {
if (buffer().isEmpty()) {
}
const auto ruleSetIndex = ruleSetMap[rule.ruleId];
return true;
});
}
void ConfUtil::writeZone(const IpRange &ipRange) void ConfUtil::writeZone(const IpRange &ipRange)
{ {
const int addrSize = FORT_CONF_ADDR_LIST_SIZE( const int addrSize = FORT_CONF_ADDR_LIST_SIZE(
@ -467,7 +484,7 @@ bool ConfUtil::parseAppGroups(EnvManager &envManager, const QList<AppGroup *> &a
} }
bool ConfUtil::parseExeApps( bool ConfUtil::parseExeApps(
EnvManager &envManager, ConfAppsWalker *confAppsWalker, AppParseOptions &opt) EnvManager &envManager, const ConfAppsWalker *confAppsWalker, AppParseOptions &opt)
{ {
if (Q_UNLIKELY(!confAppsWalker)) if (Q_UNLIKELY(!confAppsWalker))
return true; return true;

View File

@ -14,6 +14,7 @@ class AddressGroup;
class App; class App;
class AppGroup; class AppGroup;
class ConfAppsWalker; class ConfAppsWalker;
class ConfRulesWalker;
class EnvManager; class EnvManager;
class FirewallConf; class FirewallConf;
@ -51,10 +52,13 @@ public slots:
void writeVersion(); void writeVersion();
void writeServices(const QVector<ServiceInfo> &services, int runningServicesCount); void writeServices(const QVector<ServiceInfo> &services, int runningServicesCount);
bool write(const FirewallConf &conf, ConfAppsWalker *confAppsWalker, EnvManager &envManager); bool write(
const FirewallConf &conf, const ConfAppsWalker *confAppsWalker, EnvManager &envManager);
void writeFlags(const FirewallConf &conf); void writeFlags(const FirewallConf &conf);
bool writeAppEntry(const App &app, bool isNew = false); bool writeAppEntry(const App &app, bool isNew = false);
bool writeRules(const ConfRulesWalker &confRulesWalker);
void writeZone(const IpRange &ipRange); void writeZone(const IpRange &ipRange);
void writeZones(quint32 zonesMask, quint32 enabledMask, quint32 dataSize, void writeZones(quint32 zonesMask, quint32 enabledMask, quint32 dataSize,
const QList<QByteArray> &zonesData); const QList<QByteArray> &zonesData);
@ -92,7 +96,8 @@ private:
bool parseAppGroups(EnvManager &envManager, const QList<AppGroup *> &appGroups, bool parseAppGroups(EnvManager &envManager, const QList<AppGroup *> &appGroups,
ParseAppGroupsArgs &gr, AppParseOptions &opt); ParseAppGroupsArgs &gr, AppParseOptions &opt);
bool parseExeApps(EnvManager &envManager, ConfAppsWalker *confAppsWalker, AppParseOptions &opt); bool parseExeApps(
EnvManager &envManager, const ConfAppsWalker *confAppsWalker, AppParseOptions &opt);
bool parseAppsText(EnvManager &envManager, App &app, AppParseOptions &opt); bool parseAppsText(EnvManager &envManager, App &app, AppParseOptions &opt);