UI: Extract ConfData, ConfConstData from ConfUtil

This commit is contained in:
Nodir Temirkhodjaev 2024-10-31 14:54:30 +05:00
parent d50961165f
commit c4d998074e
10 changed files with 504 additions and 447 deletions

View File

@ -191,6 +191,8 @@ SOURCES += \
util/conf/addressrange.cpp \
util/conf/appparseoptions.cpp \
util/conf/confbuffer.cpp \
util/conf/confconstdata.cpp \
util/conf/confdata.cpp \
util/conf/confutil.cpp \
util/conf/ruletextparser.cpp \
util/dateutil.cpp \
@ -421,8 +423,11 @@ HEADERS += \
util/classhelpers.h \
util/conf/addressrange.h \
util/conf/appparseoptions.h \
util/conf/conf_types.h \
util/conf/confappswalker.h \
util/conf/confbuffer.h \
util/conf/confconstdata.h \
util/conf/confdata.h \
util/conf/confruleswalker.h \
util/conf/confutil.h \
util/conf/ruletextparser.h \

View File

@ -0,0 +1,7 @@
#pragma once
#include <QVector>
using longs_arr_t = QVector<quint32>;
using shorts_arr_t = QVector<quint16>;
using chars_arr_t = QVector<qint8>;

View File

@ -16,7 +16,9 @@
#include <util/stringutil.h>
#include "confappswalker.h"
#include "confconstdata.h"
#include "confruleswalker.h"
#include "confutil.h"
#include "ruletextparser.h"
#define APP_GROUP_MAX FORT_CONF_GROUP_MAX
@ -213,7 +215,7 @@ bool ConfBuffer::write(
// Fill the buffer
char *data = buffer().data();
ConfUtil::writeConf(&data, wca, opt);
ConfData(data).writeConf(wca, opt);
return true;
}
@ -228,7 +230,7 @@ void ConfBuffer::writeFlags(const FirewallConf &conf)
// Fill the buffer
char *data = buffer().data();
ConfUtil::writeConfFlags(&data, conf);
ConfData(data).writeConfFlags(conf);
}
bool ConfBuffer::writeAppEntry(const App &app, bool isNew)
@ -245,7 +247,7 @@ bool ConfBuffer::writeAppEntry(const App &app, bool isNew)
// Fill the buffer
char *data = buffer().data();
ConfUtil::writeApps(&data, appsMap);
ConfData(data).writeApps(appsMap);
return true;
}
@ -284,7 +286,7 @@ void ConfBuffer::writeZone(const IpRange &ipRange)
// Fill the buffer
char *data = buffer().data();
ConfUtil::writeAddressList(&data, ipRange);
ConfData(data).writeAddressList(ipRange);
}
void ConfBuffer::writeZones(quint32 zonesMask, quint32 enabledMask, quint32 dataSize,
@ -307,6 +309,8 @@ void ConfBuffer::writeZones(quint32 zonesMask, quint32 enabledMask, quint32 data
data = confZones->data;
ConfData confUtilData(data);
for (const auto &zoneData : zonesData) {
Q_ASSERT(!zoneData.isEmpty());
@ -316,8 +320,8 @@ void ConfBuffer::writeZones(quint32 zonesMask, quint32 enabledMask, quint32 data
#define CONF_DATA_OFFSET quint32(data - confZones->data)
confZones->addr_off[zoneIndex] = CONF_DATA_OFFSET;
ConfUtil::writeArray(&data, zoneData);
ConfUtil::migrateZoneData(&data, zoneData);
confUtilData.writeArray(zoneData);
confUtilData.migrateZoneData(zoneData);
#undef CONF_DATA_OFFSET
zonesMask ^= zoneMask;
@ -345,7 +349,7 @@ bool ConfBuffer::loadZone(IpRange &ipRange)
const char *data = buffer().data();
uint bufSize = buffer().size();
return ConfUtil::loadAddressList(&data, ipRange, bufSize);
return ConfConstData(data).loadAddressList(ipRange, bufSize);
}
bool ConfBuffer::parseAddressGroups(const QList<AddressGroup *> &addressGroups,
@ -603,7 +607,7 @@ void ConfBuffer::writeRule(
const auto array = QByteArray::fromRawData(
(const char *) &ruleSetIds[ruleSetInfo.index], ruleSetCount * sizeof(quint16));
ConfUtil::writeArray(&data, array);
ConfData(data).writeArray(array);
}
// Write the rule's conditions

View File

@ -6,7 +6,7 @@
#include <util/conf/confappswalker.h>
#include <util/conf/confruleswalker.h>
#include "confutil.h"
#include "confdata.h"
class AddressGroup;
class AppGroup;

View File

@ -0,0 +1,68 @@
#include "confconstdata.h"
#include <common/fortconf.h>
ConfConstData::ConfConstData(const void *data) : m_data((const char *) data) { }
bool ConfConstData::loadAddressList(IpRange &ipRange, uint &bufSize)
{
return loadIpRange(ipRange, bufSize)
&& (bufSize == 0 || loadIpRange(ipRange, bufSize, /*isIPv6=*/true));
}
bool ConfConstData::loadIpRange(IpRange &ipRange, uint &bufSize, bool isIPv6)
{
if (bufSize < FORT_CONF_ADDR_LIST_OFF)
return false;
PFORT_CONF_ADDR_LIST addr_list = PFORT_CONF_ADDR_LIST(m_data);
m_data = (const char *) addr_list->ip;
const uint addrListSize = isIPv6
? FORT_CONF_ADDR6_LIST_SIZE(addr_list->ip_n, addr_list->pair_n)
: FORT_CONF_ADDR4_LIST_SIZE(addr_list->ip_n, addr_list->pair_n);
if (bufSize < addrListSize)
return false;
bufSize -= addrListSize;
if (isIPv6) {
ipRange.ip6Array().resize(addr_list->ip_n);
ipRange.pair6FromArray().resize(addr_list->pair_n);
ipRange.pair6ToArray().resize(addr_list->pair_n);
loadIp6Array(ipRange.ip6Array());
loadIp6Array(ipRange.pair6FromArray());
loadIp6Array(ipRange.pair6ToArray());
} else {
ipRange.ip4Array().resize(addr_list->ip_n);
ipRange.pair4FromArray().resize(addr_list->pair_n);
ipRange.pair4ToArray().resize(addr_list->pair_n);
loadLongs(ipRange.ip4Array());
loadLongs(ipRange.pair4FromArray());
loadLongs(ipRange.pair4ToArray());
}
return true;
}
void ConfConstData::loadLongs(longs_arr_t &array)
{
loadData(array.data(), array.size(), sizeof(quint32));
}
void ConfConstData::loadIp6Array(ip6_arr_t &array)
{
loadData(array.data(), array.size(), sizeof(ip6_addr_t));
}
void ConfConstData::loadData(void *dst, int elemCount, uint elemSize)
{
const size_t arraySize = size_t(elemCount) * elemSize;
memcpy(dst, m_data, arraySize);
m_data += arraySize;
}

View File

@ -0,0 +1,26 @@
#ifndef CONFCONSTDATA_H
#define CONFCONSTDATA_H
#include <QObject>
#include <util/net/iprange.h>
#include "conf_types.h"
class ConfConstData
{
public:
explicit ConfConstData(const void *data);
bool loadAddressList(IpRange &ipRange, uint &bufSize);
bool loadIpRange(IpRange &ipRange, uint &bufSize, bool isIPv6 = false);
void loadLongs(longs_arr_t &array);
void loadIp6Array(ip6_arr_t &array);
void loadData(void *dst, int elemCount, uint elemSize);
private:
const char *m_data = nullptr;
};
#endif // CONFCONSTDATA_H

View File

@ -0,0 +1,323 @@
#include "confdata.h"
#include <conf/appgroup.h>
#include <conf/firewallconf.h>
namespace {
void writeAppGroupFlags(PFORT_CONF_GROUP out, const FirewallConf &conf)
{
out->group_bits = 0;
out->log_blocked = 0;
out->log_conn = 0;
int i = 0;
for (const AppGroup *appGroup : conf.appGroups()) {
if (appGroup->enabled()) {
out->group_bits |= (1 << i);
}
if (appGroup->logBlocked()) {
out->log_blocked |= (1 << i);
}
if (appGroup->logConn()) {
out->log_conn |= (1 << i);
}
++i;
}
}
void writeLimitBps(PFORT_SPEED_LIMIT limit, quint32 kBits)
{
limit->bps = quint64(kBits) * (1024LL / 8); /* to bytes per second */
}
void writeLimitIn(PFORT_SPEED_LIMIT limit, const AppGroup *appGroup)
{
limit->plr = appGroup->limitPacketLoss();
limit->latency_ms = appGroup->limitLatency();
limit->buffer_bytes = appGroup->limitBufferSizeIn();
writeLimitBps(limit, appGroup->speedLimitIn());
}
void writeLimitOut(PFORT_SPEED_LIMIT limit, const AppGroup *appGroup)
{
limit->plr = appGroup->limitPacketLoss();
limit->latency_ms = appGroup->limitLatency();
limit->buffer_bytes = appGroup->limitBufferSizeOut();
writeLimitBps(limit, appGroup->speedLimitOut());
}
void writeLimits(PFORT_CONF_GROUP out, const QList<AppGroup *> &appGroups)
{
PFORT_SPEED_LIMIT limits = out->limits;
out->limit_bits = 0;
out->limit_io_bits = 0;
const int groupsCount = appGroups.size();
for (int i = 0; i < groupsCount; ++i, limits += 2) {
const AppGroup *appGroup = appGroups.at(i);
const quint32 limitIn = appGroup->enabledSpeedLimitIn();
const quint32 limitOut = appGroup->enabledSpeedLimitOut();
const bool isLimitIn = (limitIn != 0);
const bool isLimitOut = (limitOut != 0);
if (isLimitIn || isLimitOut) {
out->limit_bits |= (1 << i);
if (isLimitIn) {
out->limit_io_bits |= (1 << (i * 2 + 0));
writeLimitIn(&limits[0], appGroup);
}
if (isLimitOut) {
out->limit_io_bits |= (1 << (i * 2 + 1));
writeLimitOut(&limits[1], appGroup);
}
}
}
}
}
ConfData::ConfData(void *data) : m_data((char *) data) { }
void ConfData::writeConf(const WriteConfArgs &wca, AppParseOptions &opt)
{
PFORT_CONF_IO drvConfIo = PFORT_CONF_IO(m_data);
PFORT_CONF drvConf = &drvConfIo->conf;
quint32 addrGroupsOff;
quint32 wildAppsOff, prefixAppsOff, exeAppsOff;
m_data = drvConf->data;
#define CONF_DATA_OFFSET quint32(m_data - drvConf->data)
addrGroupsOff = CONF_DATA_OFFSET;
writeLongs(wca.ad.addressGroupOffsets);
writeAddressRanges(wca.ad.addressRanges);
wildAppsOff = CONF_DATA_OFFSET;
writeApps(opt.wildAppsMap);
prefixAppsOff = CONF_DATA_OFFSET;
writeApps(opt.prefixAppsMap, /*useHeader=*/true);
exeAppsOff = CONF_DATA_OFFSET;
writeApps(opt.exeAppsMap);
#undef CONF_DATA_OFFSET
PFORT_CONF_GROUP conf_group = &drvConfIo->conf_group;
writeAppGroupFlags(conf_group, wca.conf);
writeLimits(conf_group, wca.conf.appGroups());
ConfData(&drvConf->flags).writeConfFlags(wca.conf);
drvConf->proc_wild = opt.procWild;
drvConf->wild_apps_n = quint16(opt.wildAppsMap.size());
drvConf->prefix_apps_n = quint16(opt.prefixAppsMap.size());
drvConf->exe_apps_n = quint16(opt.exeAppsMap.size());
drvConf->addr_groups_off = addrGroupsOff;
drvConf->wild_apps_off = wildAppsOff;
drvConf->prefix_apps_off = prefixAppsOff;
drvConf->exe_apps_off = exeAppsOff;
}
void ConfData::writeConfFlags(const FirewallConf &conf)
{
PFORT_CONF_FLAGS confFlags = PFORT_CONF_FLAGS(m_data);
confFlags->boot_filter = conf.bootFilter();
confFlags->filter_enabled = conf.filterEnabled();
confFlags->filter_locals = conf.filterLocals();
confFlags->filter_local_net = conf.filterLocalNet();
confFlags->block_traffic = conf.blockTraffic();
confFlags->block_inet_traffic = conf.blockInetTraffic();
confFlags->allow_all_new = conf.allowAllNew();
confFlags->ask_to_connect = conf.askToConnect();
confFlags->group_blocked = conf.groupBlocked();
confFlags->app_block_all = conf.appBlockAll();
confFlags->app_allow_all = conf.appAllowAll();
confFlags->log_stat = true; // always enabled for driver
confFlags->log_stat_no_filter = conf.logStatNoFilter();
confFlags->log_blocked = conf.logBlocked();
confFlags->log_allowed_ip = conf.logAllowedIp();
confFlags->log_blocked_ip = conf.logBlockedIp();
confFlags->log_alerted_blocked_ip = conf.logAlertedBlockedIp();
confFlags->group_bits = conf.activeGroupBits();
}
void ConfData::writeAddressRanges(const addrranges_arr_t &addressRanges)
{
for (const AddressRange &addressRange : addressRanges) {
writeAddressRange(addressRange);
}
}
void ConfData::writeAddressRange(const AddressRange &addressRange)
{
PFORT_CONF_ADDR_GROUP addrGroup = PFORT_CONF_ADDR_GROUP(m_data);
addrGroup->include_all = addressRange.includeAll();
addrGroup->exclude_all = addressRange.excludeAll();
addrGroup->include_zones = addressRange.includeZones();
addrGroup->exclude_zones = addressRange.excludeZones();
addrGroup->include_is_empty = addressRange.includeRange().isEmpty();
addrGroup->exclude_is_empty = addressRange.excludeRange().isEmpty();
m_data += FORT_CONF_ADDR_GROUP_OFF;
writeAddressList(addressRange.includeRange());
addrGroup->exclude_off = m_data - addrGroup->data;
writeAddressList(addressRange.excludeRange());
}
void ConfData::writeAddressList(const IpRange &ipRange)
{
writeIpRange(ipRange);
writeIpRange(ipRange, /*isIPv6=*/true);
}
void ConfData::writeIpRange(const IpRange &ipRange, bool isIPv6)
{
PFORT_CONF_ADDR_LIST addrList = PFORT_CONF_ADDR_LIST(m_data);
addrList->ip_n = quint32(isIPv6 ? ipRange.ip6Size() : ipRange.ip4Size());
addrList->pair_n = quint32(isIPv6 ? ipRange.pair6Size() : ipRange.pair4Size());
m_data += FORT_CONF_ADDR_LIST_OFF;
if (isIPv6) {
writeIp6Array(ipRange.ip6Array());
writeIp6Array(ipRange.pair6FromArray());
writeIp6Array(ipRange.pair6ToArray());
} else {
writeLongs(ipRange.ip4Array());
writeLongs(ipRange.pair4FromArray());
writeLongs(ipRange.pair4ToArray());
}
}
void ConfData::writeApps(const appdata_map_t &appsMap, bool useHeader)
{
quint32 *offp = (quint32 *) m_data;
const quint32 offTableSize = quint32(useHeader ? FORT_CONF_STR_HEADER_SIZE(appsMap.size()) : 0);
char *p = m_data + offTableSize;
quint32 off = 0;
if (useHeader) {
*offp++ = 0;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
for (const auto &[kernelPath, appData] : appsMap.asKeyValueRange()) {
#else
auto it = appsMap.constBegin();
for (; it != appsMap.constEnd(); ++it) {
const auto &kernelPath = it.key();
const auto &appData = it.value();
#endif
const int kernelPathSize = kernelPath.size();
const quint16 appPathLen = quint16(kernelPathSize * sizeof(wchar_t));
const quint32 appSize = FORT_CONF_APP_ENTRY_SIZE(appPathLen);
PFORT_APP_ENTRY entry = PFORT_APP_ENTRY(p);
entry->app_data = appData;
entry->path_len = appPathLen;
kernelPath.toWCharArray(entry->path);
entry->path[kernelPathSize] = L'\0';
off += appSize;
if (useHeader) {
*offp++ = off;
}
p += appSize;
}
m_data += offTableSize + FORT_CONF_STR_DATA_SIZE(off);
}
void ConfData::migrateZoneData(const QByteArray &zoneData)
{
PFORT_CONF_ADDR_LIST addr_list = PFORT_CONF_ADDR_LIST(zoneData.data());
if (FORT_CONF_ADDR4_LIST_SIZE(addr_list->ip_n, addr_list->pair_n) == zoneData.size()) {
IpRange ipRange;
writeIpRange(ipRange, /*isIPv6=*/true);
}
}
void ConfData::writeShorts(const shorts_arr_t &array)
{
writeData(array.constData(), array.size(), sizeof(quint16));
}
void ConfData::writeLongs(const longs_arr_t &array)
{
writeData(array.constData(), array.size(), sizeof(quint32));
}
void ConfData::writeIp6Array(const ip6_arr_t &array)
{
writeData(array.constData(), array.size(), sizeof(ip6_addr_t));
}
void ConfData::writeData(void const *src, int elemCount, uint elemSize)
{
const size_t arraySize = size_t(elemCount) * elemSize;
memcpy(m_data, src, arraySize);
m_data += arraySize;
}
void ConfData::writeChars(const chars_arr_t &array)
{
const size_t arraySize = size_t(array.size());
memcpy(m_data, array.constData(), arraySize);
m_data += FORT_CONF_STR_DATA_SIZE(arraySize);
}
void ConfData::writeArray(const QByteArray &array)
{
const size_t arraySize = size_t(array.size());
memcpy(m_data, array.constData(), arraySize);
m_data += arraySize;
}
void ConfData::writeString(const QString &s)
{
wchar_t *array = (wchar_t *) m_data;
const int n = s.toWCharArray(array);
array[n] = L'\0';
m_data += (n + 1) * sizeof(wchar_t); // +1 for the null terminator
}

View File

@ -0,0 +1,60 @@
#ifndef CONFDATA_H
#define CONFDATA_H
#include <QByteArray>
#include <QObject>
#include <util/service/serviceinfo.h>
#include "appparseoptions.h"
#include "conf_types.h"
class FirewallConf;
struct ParseAddressGroupsArgs
{
addrranges_arr_t addressRanges;
longs_arr_t addressGroupOffsets;
};
struct WriteConfArgs
{
const FirewallConf &conf;
ParseAddressGroupsArgs ad;
};
class ConfData
{
public:
explicit ConfData(void *data);
void writeConf(const WriteConfArgs &wca, AppParseOptions &opt);
void writeConfFlags(const FirewallConf &conf);
void writeAddressRanges(const addrranges_arr_t &addressRanges);
void writeAddressRange(const AddressRange &addressRange);
void writeAddressList(const IpRange &ipRange);
void writeIpRange(const IpRange &ipRange, bool isIPv6 = false);
bool loadAddressList(IpRange &ipRange, uint &bufSize);
bool loadIpRange(IpRange &ipRange, uint &bufSize, bool isIPv6 = false);
void writeApps(const appdata_map_t &appsMap, bool useHeader = false);
void migrateZoneData(const QByteArray &zoneData);
void writeShorts(const shorts_arr_t &array);
void writeLongs(const longs_arr_t &array);
void writeIp6Array(const ip6_arr_t &array);
void writeData(void const *src, int elemCount, uint elemSize);
void writeChars(const chars_arr_t &array);
void writeArray(const QByteArray &array);
void writeString(const QString &s);
private:
char *m_data = nullptr;
};
#endif // CONFDATA_H

View File

@ -1,92 +1,9 @@
#include "confutil.h"
#include <conf/appgroup.h>
#include <conf/firewallconf.h>
#include <common/fortconf.h>
#include <util/stringutil.h>
namespace {
void writeAppGroupFlags(PFORT_CONF_GROUP out, const FirewallConf &conf)
{
out->group_bits = 0;
out->log_blocked = 0;
out->log_conn = 0;
int i = 0;
for (const AppGroup *appGroup : conf.appGroups()) {
if (appGroup->enabled()) {
out->group_bits |= (1 << i);
}
if (appGroup->logBlocked()) {
out->log_blocked |= (1 << i);
}
if (appGroup->logConn()) {
out->log_conn |= (1 << i);
}
++i;
}
}
void writeLimitBps(PFORT_SPEED_LIMIT limit, quint32 kBits)
{
limit->bps = quint64(kBits) * (1024LL / 8); /* to bytes per second */
}
void writeLimitIn(PFORT_SPEED_LIMIT limit, const AppGroup *appGroup)
{
limit->plr = appGroup->limitPacketLoss();
limit->latency_ms = appGroup->limitLatency();
limit->buffer_bytes = appGroup->limitBufferSizeIn();
writeLimitBps(limit, appGroup->speedLimitIn());
}
void writeLimitOut(PFORT_SPEED_LIMIT limit, const AppGroup *appGroup)
{
limit->plr = appGroup->limitPacketLoss();
limit->latency_ms = appGroup->limitLatency();
limit->buffer_bytes = appGroup->limitBufferSizeOut();
writeLimitBps(limit, appGroup->speedLimitOut());
}
void writeLimits(PFORT_CONF_GROUP out, const QList<AppGroup *> &appGroups)
{
PFORT_SPEED_LIMIT limits = out->limits;
out->limit_bits = 0;
out->limit_io_bits = 0;
const int groupsCount = appGroups.size();
for (int i = 0; i < groupsCount; ++i, limits += 2) {
const AppGroup *appGroup = appGroups.at(i);
const quint32 limitIn = appGroup->enabledSpeedLimitIn();
const quint32 limitOut = appGroup->enabledSpeedLimitOut();
const bool isLimitIn = (limitIn != 0);
const bool isLimitOut = (limitOut != 0);
if (isLimitIn || isLimitOut) {
out->limit_bits |= (1 << i);
if (isLimitIn) {
out->limit_io_bits |= (1 << (i * 2 + 0));
writeLimitIn(&limits[0], appGroup);
}
if (isLimitOut) {
out->limit_io_bits |= (1 << (i * 2 + 1));
writeLimitOut(&limits[1], appGroup);
}
}
}
}
}
int ConfUtil::ruleMaxCount()
{
return FORT_CONF_RULE_MAX;
@ -141,301 +58,3 @@ QString ConfUtil::parseAppPath(const QStringView &line, bool &isWild, bool &isPr
return path.toString();
}
void ConfUtil::writeConf(char **data, const WriteConfArgs &wca, AppParseOptions &opt)
{
PFORT_CONF_IO drvConfIo = PFORT_CONF_IO(*data);
PFORT_CONF drvConf = &drvConfIo->conf;
quint32 addrGroupsOff;
quint32 wildAppsOff, prefixAppsOff, exeAppsOff;
*data = drvConf->data;
#define CONF_DATA_OFFSET quint32(*data - drvConf->data)
addrGroupsOff = CONF_DATA_OFFSET;
writeLongs(data, wca.ad.addressGroupOffsets);
writeAddressRanges(data, wca.ad.addressRanges);
wildAppsOff = CONF_DATA_OFFSET;
writeApps(data, opt.wildAppsMap);
prefixAppsOff = CONF_DATA_OFFSET;
writeApps(data, opt.prefixAppsMap, /*useHeader=*/true);
exeAppsOff = CONF_DATA_OFFSET;
writeApps(data, opt.exeAppsMap);
#undef CONF_DATA_OFFSET
PFORT_CONF_GROUP conf_group = &drvConfIo->conf_group;
writeAppGroupFlags(conf_group, wca.conf);
writeLimits(conf_group, wca.conf.appGroups());
*data = (char *) &drvConf->flags;
writeConfFlags(data, wca.conf);
drvConf->proc_wild = opt.procWild;
drvConf->wild_apps_n = quint16(opt.wildAppsMap.size());
drvConf->prefix_apps_n = quint16(opt.prefixAppsMap.size());
drvConf->exe_apps_n = quint16(opt.exeAppsMap.size());
drvConf->addr_groups_off = addrGroupsOff;
drvConf->wild_apps_off = wildAppsOff;
drvConf->prefix_apps_off = prefixAppsOff;
drvConf->exe_apps_off = exeAppsOff;
}
void ConfUtil::writeConfFlags(char **data, const FirewallConf &conf)
{
PFORT_CONF_FLAGS confFlags = PFORT_CONF_FLAGS(*data);
confFlags->boot_filter = conf.bootFilter();
confFlags->filter_enabled = conf.filterEnabled();
confFlags->filter_locals = conf.filterLocals();
confFlags->filter_local_net = conf.filterLocalNet();
confFlags->block_traffic = conf.blockTraffic();
confFlags->block_inet_traffic = conf.blockInetTraffic();
confFlags->allow_all_new = conf.allowAllNew();
confFlags->ask_to_connect = conf.askToConnect();
confFlags->group_blocked = conf.groupBlocked();
confFlags->app_block_all = conf.appBlockAll();
confFlags->app_allow_all = conf.appAllowAll();
confFlags->log_stat = true; // always enabled for driver
confFlags->log_stat_no_filter = conf.logStatNoFilter();
confFlags->log_blocked = conf.logBlocked();
confFlags->log_allowed_ip = conf.logAllowedIp();
confFlags->log_blocked_ip = conf.logBlockedIp();
confFlags->log_alerted_blocked_ip = conf.logAlertedBlockedIp();
confFlags->group_bits = conf.activeGroupBits();
}
void ConfUtil::writeAddressRanges(char **data, const addrranges_arr_t &addressRanges)
{
for (const AddressRange &addressRange : addressRanges) {
writeAddressRange(data, addressRange);
}
}
void ConfUtil::writeAddressRange(char **data, const AddressRange &addressRange)
{
PFORT_CONF_ADDR_GROUP addrGroup = PFORT_CONF_ADDR_GROUP(*data);
addrGroup->include_all = addressRange.includeAll();
addrGroup->exclude_all = addressRange.excludeAll();
addrGroup->include_zones = addressRange.includeZones();
addrGroup->exclude_zones = addressRange.excludeZones();
addrGroup->include_is_empty = addressRange.includeRange().isEmpty();
addrGroup->exclude_is_empty = addressRange.excludeRange().isEmpty();
*data += FORT_CONF_ADDR_GROUP_OFF;
writeAddressList(data, addressRange.includeRange());
addrGroup->exclude_off = *data - addrGroup->data;
writeAddressList(data, addressRange.excludeRange());
}
void ConfUtil::writeAddressList(char **data, const IpRange &ipRange)
{
writeIpRange(data, ipRange);
writeIpRange(data, ipRange, /*isIPv6=*/true);
}
void ConfUtil::writeIpRange(char **data, const IpRange &ipRange, bool isIPv6)
{
PFORT_CONF_ADDR_LIST addrList = PFORT_CONF_ADDR_LIST(*data);
addrList->ip_n = quint32(isIPv6 ? ipRange.ip6Size() : ipRange.ip4Size());
addrList->pair_n = quint32(isIPv6 ? ipRange.pair6Size() : ipRange.pair4Size());
*data += FORT_CONF_ADDR_LIST_OFF;
if (isIPv6) {
writeIp6Array(data, ipRange.ip6Array());
writeIp6Array(data, ipRange.pair6FromArray());
writeIp6Array(data, ipRange.pair6ToArray());
} else {
writeLongs(data, ipRange.ip4Array());
writeLongs(data, ipRange.pair4FromArray());
writeLongs(data, ipRange.pair4ToArray());
}
}
bool ConfUtil::loadAddressList(const char **data, IpRange &ipRange, uint &bufSize)
{
return loadIpRange(data, ipRange, bufSize)
&& (bufSize == 0 || loadIpRange(data, ipRange, bufSize, /*isIPv6=*/true));
}
bool ConfUtil::loadIpRange(const char **data, IpRange &ipRange, uint &bufSize, bool isIPv6)
{
if (bufSize < FORT_CONF_ADDR_LIST_OFF)
return false;
PFORT_CONF_ADDR_LIST addr_list = PFORT_CONF_ADDR_LIST(*data);
*data = (const char *) addr_list->ip;
const uint addrListSize = isIPv6
? FORT_CONF_ADDR6_LIST_SIZE(addr_list->ip_n, addr_list->pair_n)
: FORT_CONF_ADDR4_LIST_SIZE(addr_list->ip_n, addr_list->pair_n);
if (bufSize < addrListSize)
return false;
bufSize -= addrListSize;
if (isIPv6) {
ipRange.ip6Array().resize(addr_list->ip_n);
ipRange.pair6FromArray().resize(addr_list->pair_n);
ipRange.pair6ToArray().resize(addr_list->pair_n);
loadIp6Array(data, ipRange.ip6Array());
loadIp6Array(data, ipRange.pair6FromArray());
loadIp6Array(data, ipRange.pair6ToArray());
} else {
ipRange.ip4Array().resize(addr_list->ip_n);
ipRange.pair4FromArray().resize(addr_list->pair_n);
ipRange.pair4ToArray().resize(addr_list->pair_n);
loadLongs(data, ipRange.ip4Array());
loadLongs(data, ipRange.pair4FromArray());
loadLongs(data, ipRange.pair4ToArray());
}
return true;
}
void ConfUtil::writeApps(char **data, const appdata_map_t &appsMap, bool useHeader)
{
quint32 *offp = (quint32 *) *data;
const quint32 offTableSize = quint32(useHeader ? FORT_CONF_STR_HEADER_SIZE(appsMap.size()) : 0);
char *p = *data + offTableSize;
quint32 off = 0;
if (useHeader) {
*offp++ = 0;
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
for (const auto &[kernelPath, appData] : appsMap.asKeyValueRange()) {
#else
auto it = appsMap.constBegin();
for (; it != appsMap.constEnd(); ++it) {
const auto &kernelPath = it.key();
const auto &appData = it.value();
#endif
const int kernelPathSize = kernelPath.size();
const quint16 appPathLen = quint16(kernelPathSize * sizeof(wchar_t));
const quint32 appSize = FORT_CONF_APP_ENTRY_SIZE(appPathLen);
PFORT_APP_ENTRY entry = PFORT_APP_ENTRY(p);
entry->app_data = appData;
entry->path_len = appPathLen;
kernelPath.toWCharArray(entry->path);
entry->path[kernelPathSize] = L'\0';
off += appSize;
if (useHeader) {
*offp++ = off;
}
p += appSize;
}
*data += offTableSize + FORT_CONF_STR_DATA_SIZE(off);
}
void ConfUtil::migrateZoneData(char **data, const QByteArray &zoneData)
{
PFORT_CONF_ADDR_LIST addr_list = PFORT_CONF_ADDR_LIST(zoneData.data());
if (FORT_CONF_ADDR4_LIST_SIZE(addr_list->ip_n, addr_list->pair_n) == zoneData.size()) {
IpRange ipRange;
writeIpRange(data, ipRange, /*isIPv6=*/true);
}
}
void ConfUtil::writeShorts(char **data, const shorts_arr_t &array)
{
writeData(data, array.constData(), array.size(), sizeof(quint16));
}
void ConfUtil::writeLongs(char **data, const longs_arr_t &array)
{
writeData(data, array.constData(), array.size(), sizeof(quint32));
}
void ConfUtil::writeIp6Array(char **data, const ip6_arr_t &array)
{
writeData(data, array.constData(), array.size(), sizeof(ip6_addr_t));
}
void ConfUtil::writeData(char **data, void const *src, int elemCount, uint elemSize)
{
const size_t arraySize = size_t(elemCount) * elemSize;
memcpy(*data, src, arraySize);
*data += arraySize;
}
void ConfUtil::writeChars(char **data, const chars_arr_t &array)
{
const size_t arraySize = size_t(array.size());
memcpy(*data, array.constData(), arraySize);
*data += FORT_CONF_STR_DATA_SIZE(arraySize);
}
void ConfUtil::writeArray(char **data, const QByteArray &array)
{
const size_t arraySize = size_t(array.size());
memcpy(*data, array.constData(), arraySize);
*data += arraySize;
}
void ConfUtil::writeString(char **data, const QString &s)
{
wchar_t *array = (wchar_t *) *data;
const int n = s.toWCharArray(array);
array[n] = L'\0';
*data += (n + 1) * sizeof(wchar_t); // +1 for the null terminator
}
void ConfUtil::loadLongs(const char **data, longs_arr_t &array)
{
loadData(data, array.data(), array.size(), sizeof(quint32));
}
void ConfUtil::loadIp6Array(const char **data, ip6_arr_t &array)
{
loadData(data, array.data(), array.size(), sizeof(ip6_addr_t));
}
void ConfUtil::loadData(const char **data, void *dst, int elemCount, uint elemSize)
{
const size_t arraySize = size_t(elemCount) * elemSize;
memcpy(dst, *data, arraySize);
*data += arraySize;
}

View File

@ -1,34 +1,8 @@
#ifndef CONFUTIL_H
#define CONFUTIL_H
#include <QByteArray>
#include <QList>
#include <QObject>
#include <QRegularExpressionMatch>
#include <QVector>
#include <util/service/serviceinfo.h>
#include "appparseoptions.h"
class FirewallConf;
using longs_arr_t = QVector<quint32>;
using shorts_arr_t = QVector<quint16>;
using chars_arr_t = QVector<qint8>;
struct ParseAddressGroupsArgs
{
addrranges_arr_t addressRanges;
longs_arr_t addressGroupOffsets;
};
struct WriteConfArgs
{
const FirewallConf &conf;
ParseAddressGroupsArgs ad;
};
class ConfUtil
{
@ -43,35 +17,6 @@ public:
static QRegularExpressionMatch matchWildcard(const QStringView &path);
static QString parseAppPath(const QStringView &line, bool &isWild, bool &isPrefix);
static void writeConf(char **data, const WriteConfArgs &wca, AppParseOptions &opt);
static void writeConfFlags(char **data, const FirewallConf &conf);
static void writeAddressRanges(char **data, const addrranges_arr_t &addressRanges);
static void writeAddressRange(char **data, const AddressRange &addressRange);
static void writeAddressList(char **data, const IpRange &ipRange);
static void writeIpRange(char **data, const IpRange &ipRange, bool isIPv6 = false);
static bool loadAddressList(const char **data, IpRange &ipRange, uint &bufSize);
static bool loadIpRange(
const char **data, IpRange &ipRange, uint &bufSize, bool isIPv6 = false);
static void writeApps(char **data, const appdata_map_t &appsMap, bool useHeader = false);
static void migrateZoneData(char **data, const QByteArray &zoneData);
static void writeShorts(char **data, const shorts_arr_t &array);
static void writeLongs(char **data, const longs_arr_t &array);
static void writeIp6Array(char **data, const ip6_arr_t &array);
static void writeData(char **data, void const *src, int elemCount, uint elemSize);
static void writeChars(char **data, const chars_arr_t &array);
static void writeArray(char **data, const QByteArray &array);
static void writeString(char **data, const QString &s);
static void loadLongs(const char **data, longs_arr_t &array);
static void loadIp6Array(const char **data, ip6_arr_t &array);
static void loadData(const char **data, void *dst, int elemCount, uint elemSize);
};
#endif // CONFUTIL_H