diff --git a/src/ui/FortFirewallUI.pro b/src/ui/FortFirewallUI.pro index 07dc18c4..b36b0779 100644 --- a/src/ui/FortFirewallUI.pro +++ b/src/ui/FortFirewallUI.pro @@ -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 \ diff --git a/src/ui/util/conf/conf_types.h b/src/ui/util/conf/conf_types.h new file mode 100644 index 00000000..7a6fea00 --- /dev/null +++ b/src/ui/util/conf/conf_types.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +using longs_arr_t = QVector; +using shorts_arr_t = QVector; +using chars_arr_t = QVector; diff --git a/src/ui/util/conf/confbuffer.cpp b/src/ui/util/conf/confbuffer.cpp index 87728b22..abd3e2ea 100644 --- a/src/ui/util/conf/confbuffer.cpp +++ b/src/ui/util/conf/confbuffer.cpp @@ -16,7 +16,9 @@ #include #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 &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 diff --git a/src/ui/util/conf/confbuffer.h b/src/ui/util/conf/confbuffer.h index 7d8230ad..d57f642d 100644 --- a/src/ui/util/conf/confbuffer.h +++ b/src/ui/util/conf/confbuffer.h @@ -6,7 +6,7 @@ #include #include -#include "confutil.h" +#include "confdata.h" class AddressGroup; class AppGroup; diff --git a/src/ui/util/conf/confconstdata.cpp b/src/ui/util/conf/confconstdata.cpp new file mode 100644 index 00000000..fcf9a226 --- /dev/null +++ b/src/ui/util/conf/confconstdata.cpp @@ -0,0 +1,68 @@ +#include "confconstdata.h" + +#include + +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; +} diff --git a/src/ui/util/conf/confconstdata.h b/src/ui/util/conf/confconstdata.h new file mode 100644 index 00000000..2c56162f --- /dev/null +++ b/src/ui/util/conf/confconstdata.h @@ -0,0 +1,26 @@ +#ifndef CONFCONSTDATA_H +#define CONFCONSTDATA_H + +#include + +#include + +#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 diff --git a/src/ui/util/conf/confdata.cpp b/src/ui/util/conf/confdata.cpp new file mode 100644 index 00000000..17a56a49 --- /dev/null +++ b/src/ui/util/conf/confdata.cpp @@ -0,0 +1,323 @@ +#include "confdata.h" + +#include +#include + +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 &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 +} diff --git a/src/ui/util/conf/confdata.h b/src/ui/util/conf/confdata.h new file mode 100644 index 00000000..0a18c8f3 --- /dev/null +++ b/src/ui/util/conf/confdata.h @@ -0,0 +1,60 @@ +#ifndef CONFDATA_H +#define CONFDATA_H + +#include +#include + +#include + +#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 diff --git a/src/ui/util/conf/confutil.cpp b/src/ui/util/conf/confutil.cpp index 19ae8328..b9686e3f 100644 --- a/src/ui/util/conf/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -1,92 +1,9 @@ #include "confutil.h" -#include -#include +#include + #include -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 &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; -} diff --git a/src/ui/util/conf/confutil.h b/src/ui/util/conf/confutil.h index 2ff43b91..84d28f1c 100644 --- a/src/ui/util/conf/confutil.h +++ b/src/ui/util/conf/confutil.h @@ -1,34 +1,8 @@ #ifndef CONFUTIL_H #define CONFUTIL_H -#include -#include #include #include -#include - -#include - -#include "appparseoptions.h" - -class FirewallConf; - -using longs_arr_t = QVector; -using shorts_arr_t = QVector; -using chars_arr_t = QVector; - -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