From 8c468aaa69224195dc042abe47c4763e8e6a731a Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Sat, 20 Jan 2018 13:57:22 +0500 Subject: [PATCH] Add ability to use more IPv4 Address Groups. --- src/common/fortconf.c | 59 ++++-- src/common/fortconf.h | 31 +-- src/common/version.h | 2 +- src/driver/fortdrv.c | 49 +++-- src/tests/confutil/ConfUtil.pro | 6 +- src/tests/confutil/test.cpp | 22 +-- src/tests/logreader/LogReader.pro | 6 +- src/tests/logreader/test.cpp | 20 +- src/ui/FortFirewall.pro | 6 +- src/ui/conf/addressgroup.cpp | 47 +++-- src/ui/conf/addressgroup.h | 32 +++- src/ui/conf/firewallconf.cpp | 32 ++-- src/ui/conf/firewallconf.h | 15 +- src/ui/driver/drivermanager.cpp | 2 +- src/ui/fortcommon.cpp | 17 +- src/ui/fortcommon.h | 2 +- src/ui/fortsettings.cpp | 59 +++++- src/ui/fortsettings.h | 6 + src/ui/i18n/i18n_ru.qm | Bin 9791 -> 9895 bytes src/ui/i18n/i18n_ru.ts | 35 ++-- src/ui/qml/pages/AddressesPage.qml | 26 ++- .../qml/pages/addresses/AddressesColumn.qml | 16 +- src/ui/task/tasktasix.cpp | 6 +- src/ui/util/conf/addressrange.cpp | 7 + src/ui/util/conf/addressrange.h | 34 ++++ src/ui/util/{ => conf}/confutil.cpp | 181 +++++++++++------- src/ui/util/{ => conf}/confutil.h | 28 ++- src/ui/util/net/ip4range.cpp | 12 +- src/ui/util/net/ip4range.h | 2 + 29 files changed, 516 insertions(+), 244 deletions(-) create mode 100644 src/ui/util/conf/addressrange.cpp create mode 100644 src/ui/util/conf/addressrange.h rename src/ui/util/{ => conf}/confutil.cpp (65%) rename src/ui/util/{ => conf}/confutil.h (66%) diff --git a/src/common/fortconf.c b/src/common/fortconf.c index af44aaa8..d4317e92 100644 --- a/src/common/fortconf.c +++ b/src/common/fortconf.c @@ -15,8 +15,7 @@ fort_memcmp (const char *p1, const char *p2, size_t len) #endif static BOOL -fort_conf_ip_inrange (UINT32 ip, UINT32 count, - const UINT32 *iprange_from, const UINT32 *iprange_to) +fort_conf_ip_inrange (UINT32 ip, UINT32 count, const UINT32 *iprange) { int low, high; @@ -27,7 +26,7 @@ fort_conf_ip_inrange (UINT32 ip, UINT32 count, do { const int mid = (low + high) / 2; - const UINT32 mid_ip = iprange_from[mid]; + const UINT32 mid_ip = iprange[mid]; if (ip < mid_ip) high = mid - 1; @@ -37,32 +36,56 @@ fort_conf_ip_inrange (UINT32 ip, UINT32 count, return TRUE; } while (low <= high); - return high >= 0 && ip >= iprange_from[high] && ip <= iprange_to[high]; + return high >= 0 && ip >= iprange[high] + && ip <= iprange[count + high]; } -static BOOL -fort_conf_ip_included (const PFORT_CONF conf, UINT32 remote_ip) +static const PFORT_CONF_ADDR_GROUP +fort_conf_addr_group_ref (const PFORT_CONF conf, int addr_group_index) { - const char *data = (const char *) conf + conf->data_off; + const UINT32 *addr_group_offsets = (const UINT32 *) + (conf->data + conf->addr_groups_off); + const char *addr_group_data = (const char *) addr_group_offsets; - const BOOL include_all = conf->flags.ip_include_all; - const BOOL exclude_all = conf->flags.ip_exclude_all; + return (PFORT_CONF_ADDR_GROUP) + (addr_group_data + addr_group_offsets[addr_group_index]); +} + +#define fort_conf_addr_group_include_ref(addr_group) \ + (addr_group)->ip + +#define fort_conf_addr_group_exclude_ref(addr_group) \ + &(addr_group)->ip[(addr_group)->include_n * 2] + +static BOOL +fort_conf_ip_included (const PFORT_CONF conf, UINT32 remote_ip, + int addr_group_index) +{ + const PFORT_CONF_ADDR_GROUP addr_group = fort_conf_addr_group_ref( + conf, addr_group_index); + + const BOOL include_all = addr_group->include_all; + const BOOL exclude_all = addr_group->exclude_all; const BOOL ip_included = include_all ? TRUE - : fort_conf_ip_inrange(remote_ip, conf->ip_include_n, - (const UINT32 *) (data + conf->ip_from_include_off), - (const UINT32 *) (data + conf->ip_to_include_off)); + : fort_conf_ip_inrange(remote_ip, addr_group->include_n, + fort_conf_addr_group_include_ref(addr_group)); const BOOL ip_excluded = exclude_all ? TRUE - : fort_conf_ip_inrange(remote_ip, conf->ip_exclude_n, - (const UINT32 *) (data + conf->ip_from_exclude_off), - (const UINT32 *) (data + conf->ip_to_exclude_off)); + : fort_conf_ip_inrange(remote_ip, addr_group->exclude_n, + fort_conf_addr_group_exclude_ref(addr_group)); return include_all ? !ip_excluded : (exclude_all ? ip_included : (ip_included && !ip_excluded)); } +#define fort_conf_ip_is_inet(conf, remote_ip) \ + fort_conf_ip_included((conf), (remote_ip), 0) + +#define fort_conf_ip_inet_included(conf, remote_ip) \ + fort_conf_ip_included((conf), (remote_ip), 1) + static int fort_conf_app_cmp (UINT32 path_len, const char *path, const char *apps, const UINT32 *app_offp) @@ -90,7 +113,7 @@ fort_conf_app_index (const PFORT_CONF conf, if (count == 0) return -1; - data = (const char *) conf + conf->data_off; + data = conf->data; app_offsets = (const UINT32 *) (data + conf->apps_off); apps = (const char *) (app_offsets + count + 1); @@ -115,7 +138,7 @@ fort_conf_app_index (const PFORT_CONF conf, static UCHAR fort_conf_app_group_index (const PFORT_CONF conf, int app_index) { - const char *data = (const char *) conf + conf->data_off; + const char *data = conf->data; const UCHAR *app_groups = (const UCHAR *) (data + conf->app_groups_off); const BOOL app_found = (app_index != -1); @@ -126,7 +149,7 @@ fort_conf_app_group_index (const PFORT_CONF conf, int app_index) static BOOL fort_conf_app_blocked (const PFORT_CONF conf, int app_index) { - const char *data = (const char *) conf + conf->data_off; + const char *data = conf->data; const UINT32 *app_perms = (const UINT32 *) (data + conf->app_perms_off); diff --git a/src/common/fortconf.h b/src/common/fortconf.h index edbc70ac..b7d68b82 100644 --- a/src/common/fortconf.h +++ b/src/common/fortconf.h @@ -1,7 +1,8 @@ #ifndef FORTCONF_H #define FORTCONF_H -#define FORT_CONF_IP_MAX (1 * 1024 * 1024) +#define FORT_CONF_IP_MAX (10 * 1024 * 1024) +#define FORT_CONF_IP_RANGE_SIZE(n) ((n) * sizeof(UINT32) * 2) #define FORT_CONF_GROUP_MAX 16 #define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024) #define FORT_CONF_APP_PATH_MAX (2 * 1024) @@ -14,16 +15,24 @@ typedef struct fort_conf_flags { UINT32 filter_enabled : 1; UINT32 stop_traffic : 1; UINT32 stop_inet_traffic : 1; - UINT32 ip_include_all : 1; - UINT32 ip_exclude_all : 1; UINT32 app_block_all : 1; UINT32 app_allow_all : 1; UINT32 log_blocked : 1; UINT32 log_stat : 1; - UINT32 _reserved_ : 7; + UINT32 _reserved_ : 9; UINT32 group_bits : 16; } FORT_CONF_FLAGS, *PFORT_CONF_FLAGS; +typedef struct fort_conf_addr_group { + UINT32 include_all : 1; + UINT32 exclude_all : 1; + + UINT32 include_n; + UINT32 exclude_n; + + UINT32 ip[2]; +} FORT_CONF_ADDR_GROUP, *PFORT_CONF_ADDR_GROUP; + typedef struct fort_conf_limit { /* Bytes per 0.5 sec. */ UINT32 in_bytes; @@ -33,27 +42,18 @@ typedef struct fort_conf_limit { typedef struct fort_conf { FORT_CONF_FLAGS flags; - UINT16 data_off; - - UINT16 ip_include_n; - UINT16 ip_exclude_n; - UINT16 apps_n; UINT32 app_perms_block_mask; UINT32 app_perms_allow_mask; - UINT32 ip_from_include_off; - UINT32 ip_to_include_off; - - UINT32 ip_from_exclude_off; - UINT32 ip_to_exclude_off; + UINT32 addr_groups_off; UINT32 app_groups_off; UINT32 app_perms_off; UINT32 apps_off; - UCHAR data[4]; + char data[4]; } FORT_CONF, *PFORT_CONF; typedef struct fort_conf_io { @@ -68,5 +68,6 @@ typedef struct fort_conf_io { #define FORT_CONF_DATA_OFF offsetof(FORT_CONF, data) #define FORT_CONF_IO_CONF_OFF offsetof(FORT_CONF_IO, conf) +#define FORT_CONF_ADDR_DATA_OFF offsetof(FORT_CONF_ADDR_GROUP, ip) #endif FORTCONF_H diff --git a/src/common/version.h b/src/common/version.h index 20d483ec..b0ed6d92 100644 --- a/src/common/version.h +++ b/src/common/version.h @@ -7,6 +7,6 @@ #define APP_UPDATES_URL "https://github.com/tnodir/fort/releases" #define APP_UPDATES_API_URL "https://api.github.com/repos/tnodir/fort/releases/latest" -#define DRIVER_VERSION 4 +#define DRIVER_VERSION 5 #endif // VERSION_H diff --git a/src/driver/fortdrv.c b/src/driver/fortdrv.c index 36d2ea6a..0fffbf10 100644 --- a/src/driver/fortdrv.c +++ b/src/driver/fortdrv.c @@ -214,14 +214,12 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues, int flagsField, int remoteIpField) { PFORT_CONF_REF conf_ref; + PVOID path; FORT_CONF_FLAGS conf_flags; UINT32 flags; UINT32 remote_ip; UINT32 process_id; UINT32 path_len; - PVOID path; - int app_index; - BOOL ip_included, blocked; PIRP irp = NULL; ULONG_PTR info; @@ -252,42 +250,41 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues, if (conf_flags.stop_traffic) goto block; - if (!conf_flags.filter_enabled) + if (!conf_flags.filter_enabled + || !fort_conf_ip_is_inet(&conf_ref->conf, remote_ip)) goto permit; - ip_included = fort_conf_ip_included(&conf_ref->conf, remote_ip); - - if (ip_included && conf_flags.stop_inet_traffic) + if (conf_flags.stop_inet_traffic) goto block; process_id = (UINT32) inMetaValues->processId; path_len = inMetaValues->processPath->size - sizeof(WCHAR); // chop terminating zero path = inMetaValues->processPath->data; - blocked = ip_included - && ((app_index = fort_conf_app_index(&conf_ref->conf, path_len, path)), - fort_conf_app_blocked(&conf_ref->conf, app_index)); + if (fort_conf_ip_inet_included(&conf_ref->conf, remote_ip)) { + const int app_index = fort_conf_app_index(&conf_ref->conf, path_len, path); - if (!blocked) { - if (ip_included && conf_flags.log_stat) { - const UINT64 flowId = inMetaValues->flowHandle; - const UCHAR group_index = fort_conf_app_group_index( - &conf_ref->conf, app_index); - BOOL is_new_proc = FALSE; - NTSTATUS status; + if (!fort_conf_app_blocked(&conf_ref->conf, app_index)) { + if (conf_flags.log_stat) { + const UINT64 flowId = inMetaValues->flowHandle; + const UCHAR group_index = fort_conf_app_group_index( + &conf_ref->conf, app_index); + BOOL is_new_proc = FALSE; + NTSTATUS status; - status = fort_stat_flow_associate(&g_device->stat, - flowId, process_id, group_index, &is_new_proc); + status = fort_stat_flow_associate(&g_device->stat, + flowId, process_id, group_index, &is_new_proc); - if (!NT_SUCCESS(status)) { - DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, - "FORT: Classify v4: Flow assoc. error: %d\n", status); - } else if (is_new_proc) { - fort_buffer_proc_new_write(&g_device->buffer, - process_id, path_len, path, &irp, &info); + if (!NT_SUCCESS(status)) { + DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, + "FORT: Classify v4: Flow assoc. error: %d\n", status); + } else if (is_new_proc) { + fort_buffer_proc_new_write(&g_device->buffer, + process_id, path_len, path, &irp, &info); + } } + goto permit; } - goto permit; } if (conf_flags.log_blocked) { diff --git a/src/tests/confutil/ConfUtil.pro b/src/tests/confutil/ConfUtil.pro index 07964e3b..5fadc92b 100644 --- a/src/tests/confutil/ConfUtil.pro +++ b/src/tests/confutil/ConfUtil.pro @@ -5,7 +5,8 @@ SOURCES += \ $$UIPATH/conf/appgroup.cpp \ $$UIPATH/conf/firewallconf.cpp \ $$UIPATH/fortcommon.cpp \ - $$UIPATH/util/confutil.cpp \ + $$UIPATH/util/conf/addressrange.cpp \ + $$UIPATH/util/conf/confutil.cpp \ $$UIPATH/util/fileutil.cpp \ $$UIPATH/util/net/ip4range.cpp \ $$UIPATH/util/net/netutil.cpp @@ -15,7 +16,8 @@ HEADERS += \ $$UIPATH/conf/appgroup.h \ $$UIPATH/conf/firewallconf.h \ $$UIPATH/fortcommon.h \ - $$UIPATH/util/confutil.h \ + $$UIPATH/util/conf/addressrange.h \ + $$UIPATH/util/conf/confutil.h \ $$UIPATH/util/fileutil.h \ $$UIPATH/util/net/ip4range.h \ $$UIPATH/util/net/netutil.h diff --git a/src/tests/confutil/test.cpp b/src/tests/confutil/test.cpp index 6b5bcecb..db313e96 100644 --- a/src/tests/confutil/test.cpp +++ b/src/tests/confutil/test.cpp @@ -6,7 +6,7 @@ #include "conf/appgroup.h" #include "conf/firewallconf.h" #include "fortcommon.h" -#include "util/confutil.h" +#include "util/conf/confutil.h" #include "util/fileutil.h" #include "util/net/netutil.h" @@ -14,21 +14,19 @@ void Test::confWriteRead() { FirewallConf conf; - conf.ipInclude()->setUseAll(true); - conf.ipExclude()->setUseAll(false); + AddressGroup *inetGroup = conf.inetAddressGroup(); + + inetGroup->setIncludeAll(true); + inetGroup->setExcludeAll(false); + + inetGroup->setIncludeText(QString()); + inetGroup->setExcludeText( + NetUtil::localIpv4Networks().join('\n') + ); conf.setAppBlockAll(true); conf.setAppAllowAll(false); - conf.ipInclude()->setText(QString()); - conf.ipExclude()->setText( - "10.0.0.0/8\n" - "127.0.0.0/8\n" - "169.254.0.0/16\n" - "172.16.0.0/12\n" - "192.168.0.0/16\n" - ); - AppGroup *appGroup1 = new AppGroup(); appGroup1->setName("Base"); appGroup1->setEnabled(true); diff --git a/src/tests/logreader/LogReader.pro b/src/tests/logreader/LogReader.pro index c59b5435..a709159d 100644 --- a/src/tests/logreader/LogReader.pro +++ b/src/tests/logreader/LogReader.pro @@ -10,7 +10,8 @@ SOURCES += \ $$UIPATH/log/logentryblocked.cpp \ $$UIPATH/log/logentryprocnew.cpp \ $$UIPATH/log/logentrystattraf.cpp \ - $$UIPATH/util/confutil.cpp \ + $$UIPATH/util/conf/addressrange.cpp \ + $$UIPATH/util/conf/confutil.cpp \ $$UIPATH/util/device.cpp \ $$UIPATH/util/fileutil.cpp \ $$UIPATH/util/net/ip4range.cpp \ @@ -28,7 +29,8 @@ HEADERS += \ $$UIPATH/log/logentryblocked.h \ $$UIPATH/log/logentryprocnew.h \ $$UIPATH/log/logentrystattraf.h \ - $$UIPATH/util/confutil.h \ + $$UIPATH/util/conf/addressrange.h \ + $$UIPATH/util/conf/confutil.h \ $$UIPATH/util/device.h \ $$UIPATH/util/fileutil.h \ $$UIPATH/util/net/ip4range.h \ diff --git a/src/tests/logreader/test.cpp b/src/tests/logreader/test.cpp index e9aa8ba0..12247f5c 100644 --- a/src/tests/logreader/test.cpp +++ b/src/tests/logreader/test.cpp @@ -10,7 +10,7 @@ #include "fortcommon.h" #include "log/logbuffer.h" #include "log/logentryblocked.h" -#include "util/confutil.h" +#include "util/conf/confutil.h" #include "util/device.h" #include "util/fileutil.h" #include "util/net/netutil.h" @@ -42,22 +42,20 @@ void Test::setConf(Device &device) conf.setProvBoot(true); - conf.ipInclude()->setUseAll(true); - conf.ipExclude()->setUseAll(false); + AddressGroup *inetGroup = conf.inetAddressGroup(); + + inetGroup->setIncludeAll(true); + inetGroup->setExcludeAll(false); + + inetGroup->setExcludeText( + NetUtil::localIpv4Networks().join('\n') + ); conf.setAppBlockAll(true); conf.setAppAllowAll(false); conf.setLogBlocked(true); - conf.ipExclude()->setText( - "10.0.0.0/8\n" - "127.0.0.0/8\n" - "169.254.0.0/16\n" - "172.16.0.0/12\n" - "192.168.0.0/16\n" - ); - ConfUtil confUtil; QByteArray buf; diff --git a/src/ui/FortFirewall.pro b/src/ui/FortFirewall.pro index 70fa86c2..15207362 100644 --- a/src/ui/FortFirewall.pro +++ b/src/ui/FortFirewall.pro @@ -41,7 +41,8 @@ SOURCES += \ task/taskuzonline.cpp \ task/taskworker.cpp \ translationmanager.cpp \ - util/confutil.cpp \ + util/conf/addressrange.cpp \ + util/conf/confutil.cpp \ util/dateutil.cpp \ util/device.cpp \ util/fileutil.cpp \ @@ -89,7 +90,8 @@ HEADERS += \ task/taskuzonline.h \ task/taskworker.h \ translationmanager.h \ - util/confutil.h \ + util/conf/addressrange.h \ + util/conf/confutil.h \ util/dateutil.h \ util/device.h \ util/fileutil.h \ diff --git a/src/ui/conf/addressgroup.cpp b/src/ui/conf/addressgroup.cpp index 0b7ab9d4..5700109f 100644 --- a/src/ui/conf/addressgroup.cpp +++ b/src/ui/conf/addressgroup.cpp @@ -2,23 +2,40 @@ AddressGroup::AddressGroup(QObject *parent) : QObject(parent), - m_useAll(false) + m_includeAll(true), + m_excludeAll(false) { } -void AddressGroup::setUseAll(bool useAll) +void AddressGroup::setIncludeAll(bool includeAll) { - if (m_useAll != useAll) { - m_useAll = useAll; - emit useAllChanged(); + if (m_includeAll != includeAll) { + m_includeAll = includeAll; + emit includeAllChanged(); } } -void AddressGroup::setText(const QString &text) +void AddressGroup::setExcludeAll(bool excludeAll) { - if (m_text != text) { - m_text = text; - emit textChanged(); + if (m_excludeAll != excludeAll) { + m_excludeAll = excludeAll; + emit excludeAllChanged(); + } +} + +void AddressGroup::setIncludeText(const QString &includeText) +{ + if (m_includeText != includeText) { + m_includeText = includeText; + emit includeTextChanged(); + } +} + +void AddressGroup::setExcludeText(const QString &excludeText) +{ + if (m_excludeText != excludeText) { + m_excludeText = excludeText; + emit excludeTextChanged(); } } @@ -26,7 +43,11 @@ QVariant AddressGroup::toVariant() const { QVariantMap map; - map["text"] = text(); + map["includeAll"] = includeAll(); + map["excludeAll"] = excludeAll(); + + map["includeText"] = includeText(); + map["excludeText"] = excludeText(); return map; } @@ -35,5 +56,9 @@ void AddressGroup::fromVariant(const QVariant &v) { const QVariantMap map = v.toMap(); - m_text = map["text"].toString(); + m_includeAll = map["includeAll"].toBool(); + m_excludeAll = map["excludeAll"].toBool(); + + m_includeText = map["includeText"].toString(); + m_excludeText = map["excludeText"].toString(); } diff --git a/src/ui/conf/addressgroup.h b/src/ui/conf/addressgroup.h index 366cf39d..0e4d382e 100644 --- a/src/ui/conf/addressgroup.h +++ b/src/ui/conf/addressgroup.h @@ -7,31 +7,43 @@ class AddressGroup : public QObject { Q_OBJECT - Q_PROPERTY(bool useAll READ useAll WRITE setUseAll NOTIFY useAllChanged) - Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(bool includeAll READ includeAll WRITE setIncludeAll NOTIFY includeAllChanged) + Q_PROPERTY(bool excludeAll READ excludeAll WRITE setExcludeAll NOTIFY excludeAllChanged) + Q_PROPERTY(QString includeText READ includeText WRITE setIncludeText NOTIFY includeTextChanged) + Q_PROPERTY(QString excludeText READ excludeText WRITE setExcludeText NOTIFY excludeTextChanged) public: explicit AddressGroup(QObject *parent = nullptr); - bool useAll() const { return m_useAll; } - void setUseAll(bool useAll); + bool includeAll() const { return m_includeAll; } + void setIncludeAll(bool includeAll); - QString text() const { return m_text; } - void setText(const QString &text); + bool excludeAll() const { return m_excludeAll; } + void setExcludeAll(bool excludeAll); + + QString includeText() const { return m_includeText; } + void setIncludeText(const QString &includeText); + + QString excludeText() const { return m_excludeText; } + void setExcludeText(const QString &excludeText); QVariant toVariant() const; void fromVariant(const QVariant &v); signals: - void useAllChanged(); - void textChanged(); + void includeAllChanged(); + void excludeAllChanged(); + void includeTextChanged(); + void excludeTextChanged(); public slots: private: - uint m_useAll : 1; + uint m_includeAll : 1; + uint m_excludeAll : 1; - QString m_text; + QString m_includeText; + QString m_excludeText; }; #endif // ADDRESSGROUP_H diff --git a/src/ui/conf/firewallconf.cpp b/src/ui/conf/firewallconf.cpp index 5a120c48..d4af28be 100644 --- a/src/ui/conf/firewallconf.cpp +++ b/src/ui/conf/firewallconf.cpp @@ -22,10 +22,10 @@ FirewallConf::FirewallConf(QObject *parent) : m_trafHourKeepDays(DEFAULT_TRAF_HOUR_KEEP_DAYS), m_trafDayKeepDays(DEFAULT_TRAF_DAY_KEEP_DAYS), m_trafMonthKeepMonths(DEFAULT_TRAF_MONTH_KEEP_MONTHS), - m_trafUnit(UnitAdaptive), - m_ipInclude(new AddressGroup(this)), - m_ipExclude(new AddressGroup(this)) + m_trafUnit(UnitAdaptive) { + m_addressGroups.append(new AddressGroup(this)); + m_addressGroups.append(new AddressGroup(this)); } void FirewallConf::setProvBoot(bool provBoot) @@ -178,6 +178,11 @@ void FirewallConf::setAppGroupBits(quint32 groupBits) } } +QQmlListProperty FirewallConf::addressGroups() +{ + return QQmlListProperty(this, m_addressGroups); +} + QQmlListProperty FirewallConf::appGroups() { return QQmlListProperty(this, m_appGroups); @@ -226,8 +231,6 @@ void FirewallConf::copyFlags(const FirewallConf &o) setStopTraffic(o.stopTraffic()); setStopInetTraffic(o.stopInetTraffic()); setLogErrors(o.logErrors()); - ipInclude()->setUseAll(o.ipInclude()->useAll()); - ipExclude()->setUseAll(o.ipExclude()->useAll()); setAppBlockAll(o.appBlockAll()); setAppAllowAll(o.appAllowAll()); setPasswordHash(o.passwordHash()); @@ -255,8 +258,11 @@ QVariant FirewallConf::toVariant() const map["passwordHash"] = m_passwordHash; - map["ipInclude"] = ipInclude()->toVariant(); - map["ipExclude"] = ipExclude()->toVariant(); + QVariantList addresses; + foreach (const AddressGroup *addressGroup, addressGroupsList()) { + addresses.append(addressGroup->toVariant()); + } + map["addressGroups"] = addresses; QVariantList groups; foreach (const AppGroup *appGroup, appGroupsList()) { @@ -273,8 +279,12 @@ void FirewallConf::fromVariant(const QVariant &v) m_passwordHash = map["passwordHash"].toString(); - m_ipInclude->fromVariant(map["ipInclude"]); - m_ipExclude->fromVariant(map["ipExclude"]); + const QVariantList addresses = map["addressGroups"].toList(); + int addrGroupIndex = 0; + foreach (const QVariant &av, addresses) { + AddressGroup *addressGroup = m_addressGroups.at(addrGroupIndex++); + addressGroup->fromVariant(av); + } const QVariantList groups = map["appGroups"].toList(); foreach (const QVariant &gv, groups) { @@ -286,8 +296,8 @@ void FirewallConf::fromVariant(const QVariant &v) void FirewallConf::setupDefault() { - m_ipInclude->setUseAll(true); - m_ipExclude->setText(NetUtil::localIpv4Networks().join('\n')); + AddressGroup *inetGroup = inetAddressGroup(); + inetGroup->setExcludeText(NetUtil::localIpv4Networks().join('\n')); AppGroup *appGroup = new AppGroup(); appGroup->setName("Main"); diff --git a/src/ui/conf/firewallconf.h b/src/ui/conf/firewallconf.h index 44d5b338..9f2615c9 100644 --- a/src/ui/conf/firewallconf.h +++ b/src/ui/conf/firewallconf.h @@ -34,8 +34,8 @@ class FirewallConf : public QObject Q_PROPERTY(int trafUnit READ trafUnit WRITE setTrafUnit NOTIFY trafUnitChanged) Q_PROPERTY(bool hasPassword READ hasPassword NOTIFY passwordHashChanged) Q_PROPERTY(QString passwordHash READ passwordHash WRITE setPasswordHash NOTIFY passwordHashChanged) - Q_PROPERTY(AddressGroup *ipInclude READ ipInclude CONSTANT) - Q_PROPERTY(AddressGroup *ipExclude READ ipExclude CONSTANT) + Q_PROPERTY(AddressGroup *inetAddressGroup READ inetAddressGroup NOTIFY addressGroupsChanged) + Q_PROPERTY(QQmlListProperty addressGroups READ addressGroups NOTIFY addressGroupsChanged) Q_PROPERTY(QQmlListProperty appGroups READ appGroups NOTIFY appGroupsChanged) Q_CLASSINFO("DefaultProperty", "appGroups") @@ -105,8 +105,10 @@ public: quint32 appGroupBits() const; void setAppGroupBits(quint32 groupBits); - AddressGroup *ipInclude() const { return m_ipInclude; } - AddressGroup *ipExclude() const { return m_ipExclude; } + AddressGroup *inetAddressGroup() const { return m_addressGroups.at(0); } + + const QList &addressGroupsList() const { return m_addressGroups; } + QQmlListProperty addressGroups(); const QList &appGroupsList() const { return m_appGroups; } QQmlListProperty appGroups(); @@ -136,6 +138,7 @@ signals: void trafMonthKeepMonthsChanged(); void trafUnitChanged(); void passwordHashChanged(); + void addressGroupsChanged(); void appGroupsChanged(); public slots: @@ -169,9 +172,7 @@ private: QString m_passwordHash; - AddressGroup *m_ipInclude; - AddressGroup *m_ipExclude; - + QList m_addressGroups; QList m_appGroups; }; diff --git a/src/ui/driver/drivermanager.cpp b/src/ui/driver/drivermanager.cpp index 5d8d37e0..fbca74b9 100644 --- a/src/ui/driver/drivermanager.cpp +++ b/src/ui/driver/drivermanager.cpp @@ -5,7 +5,7 @@ #include "../conf/firewallconf.h" #include "../fortcommon.h" #include "../log/logbuffer.h" -#include "../util/confutil.h" +#include "../util/conf/confutil.h" #include "../util/device.h" #include "../util/osutil.h" #include "driverworker.h" diff --git a/src/ui/fortcommon.cpp b/src/ui/fortcommon.cpp index d0eab2cc..6f0e6f51 100644 --- a/src/ui/fortcommon.cpp +++ b/src/ui/fortcommon.cpp @@ -131,18 +131,19 @@ void FortCommon::confAppPermsMaskInit(void *drvConf) } bool FortCommon::confIpInRange(const void *drvConf, quint32 ip, - bool included) + bool included, int addrGroupIndex) { const PFORT_CONF conf = (const PFORT_CONF) drvConf; - const char *data = (const char *) conf + conf->data_off; + const PFORT_CONF_ADDR_GROUP addr_group = fort_conf_addr_group_ref( + conf, addrGroupIndex); - const quint32 count = included ? conf->ip_include_n : conf->ip_exclude_n; - const quint32 fromOff = included ? conf->ip_from_include_off : conf->ip_from_exclude_off; - const quint32 toOff = included ? conf->ip_to_include_off : conf->ip_to_exclude_off; + const UINT32 count = included ? addr_group->include_n + : addr_group->exclude_n; + const UINT32 *iprange = included + ? fort_conf_addr_group_include_ref(addr_group) + : fort_conf_addr_group_exclude_ref(addr_group); - return fort_conf_ip_inrange(ip, count, - (const quint32 *) (data + fromOff), - (const quint32 *) (data + toOff)); + return fort_conf_ip_inrange(ip, count, iprange); } int FortCommon::confAppIndex(const void *drvConf, diff --git a/src/ui/fortcommon.h b/src/ui/fortcommon.h index 7644677b..cf4150dc 100644 --- a/src/ui/fortcommon.h +++ b/src/ui/fortcommon.h @@ -51,7 +51,7 @@ public: static void confAppPermsMaskInit(void *drvConf); static bool confIpInRange(const void *drvConf, quint32 ip, - bool included = false); + bool included = false, int addrGroupIndex = 0); static int confAppIndex(const void *drvConf, const QString &kernelPath); static quint8 confAppGroupIndex(const void *drvConf, int appIndex); diff --git a/src/ui/fortsettings.cpp b/src/ui/fortsettings.cpp index 033defe6..1147f17b 100644 --- a/src/ui/fortsettings.cpp +++ b/src/ui/fortsettings.cpp @@ -160,7 +160,11 @@ bool FortSettings::tryToReadConf(FirewallConf &conf, const QString &filePath) return false; } - conf.fromVariant(jsonDoc.toVariant()); + QVariant confVar = jsonDoc.toVariant(); + + confVar = migrateConf(confVar); + + conf.fromVariant(confVar); return true; } @@ -191,6 +195,8 @@ bool FortSettings::writeConf(const FirewallConf &conf) return false; } + removeMigratedKeys(); + return true; } @@ -220,8 +226,6 @@ bool FortSettings::readConfIni(FirewallConf &conf) const conf.setLogErrors(iniBool("logErrors")); conf.setLogBlocked(iniBool("logBlocked")); conf.setLogStat(iniBool("logStat")); - conf.ipInclude()->setUseAll(iniBool("ipIncludeAll")); - conf.ipExclude()->setUseAll(iniBool("ipExcludeAll")); conf.setAppBlockAll(iniBool("appBlockAll", true)); conf.setAppAllowAll(iniBool("appAllowAll")); conf.setAppGroupBits(iniUInt("appGroupBits", DEFAULT_APP_GROUP_BITS)); @@ -249,8 +253,6 @@ bool FortSettings::writeConfIni(const FirewallConf &conf) setIniValue("logErrors", conf.logErrors()); setIniValue("logBlocked", conf.logBlocked()); setIniValue("logStat", conf.logStat()); - setIniValue("ipIncludeAll", conf.ipInclude()->useAll()); - setIniValue("ipExcludeAll", conf.ipExclude()->useAll()); setIniValue("appBlockAll", conf.appBlockAll()); setIniValue("appAllowAll", conf.appAllowAll()); setIniValue("appGroupBits", conf.appGroupBits(), DEFAULT_APP_GROUP_BITS); @@ -267,6 +269,53 @@ bool FortSettings::writeConfIni(const FirewallConf &conf) return iniSync(); } +QVariant FortSettings::migrateConf(const QVariant &confVar) +{ + const int version = iniVersion(); + if (version == APP_VERSION) + return confVar; + + QVariantMap map = confVar.toMap(); + + // 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); + + // v1.7.0: AddressGroups + if (version < 0x010700) { + removeIniKey("confFlags/ipIncludeAll"); + removeIniKey("confFlags/ipExcludeAll"); + } + + iniSync(); +} + bool FortSettings::iniBool(const QString &key, bool defaultValue) const { return iniValue(key, defaultValue).toBool(); diff --git a/src/ui/fortsettings.h b/src/ui/fortsettings.h index 05a18a2b..ce992c5c 100644 --- a/src/ui/fortsettings.h +++ b/src/ui/fortsettings.h @@ -39,6 +39,9 @@ public: QString language() const { return iniText("base/language", "en"); } void setLanguage(const QString &v) { setIniValue("base/language", v); } + int iniVersion() const { return iniInt("base/version"); } + void setIniVersion(int v) { setIniValue("base/version", v); } + QRect windowGeometry() const { return iniValue("window/geometry").toRect(); } void setWindowGeometry(const QRect &v) { setIniValue("window/geometry", v); } @@ -87,6 +90,9 @@ private: bool tryToReadConf(FirewallConf &conf, const QString &filePath); bool tryToWriteConf(const FirewallConf &conf, const QString &filePath); + QVariant migrateConf(const QVariant &confVar); + void removeMigratedKeys(); + bool iniBool(const QString &key, bool defaultValue = false) const; int iniInt(const QString &key, int defaultValue = 0) const; uint iniUInt(const QString &key, int defaultValue = 0) const; diff --git a/src/ui/i18n/i18n_ru.qm b/src/ui/i18n/i18n_ru.qm index bf6201661bc181f9723ad8adbb2d974ae7a3beb3..140bebcd1003fd2afb151ff3e198e03971bdd88d 100644 GIT binary patch delta 1188 zcmaJ=e@v8h9DeS-?|VPrdryJm;5gt;UA5^}%r1pP+_+4RVPPN+!SWU)kO2!CqOdb$ z)fhDiNureKQqdYW1^Tff7Mk>f4aBibTgkxXU^xc`rnU7LTU-D1*YkeveLv6h`8?0( z2D46XITRJV0mxn;ZUo3!16XbXndgCst-zLXz*Y-vCB|F?a)_~i06PW%cQlc;+Y51m z-z@Kg=swQAX~>=_em4O*!$aPD$jt%}^GoO)N7^;k5n*Jk-37=50d*06&)b0Y zK4hBC0m}{{)B8IR{XQ}e@O?xb@|q~%+>3&;ItmveP|qQpkvP1#3D6(GkvB;kX~1Zi z4>0W0tn2UPa_%K`RcKynJPVjTnt|ArKw`Y~z>XFKVGc=~HnaemA?bj44=^Q4ExU36 zZLajGs^ex3X=n^Ue3vxz(=Fnp*52_g;BaWy-E9Dr3)<3UPA-rpio>P+y+pM8Kj#7; zi?{a4fNoB7-=(14CqDdOCl`qoBj>bqs8h^7XbRHWIkE5!H?)n3#a|~lxk(Ow5@Hky z@=+^^t@-jt@5}?ne)%hN88<&D4|}SKXXL9x>|0SF|8nKt;B`7}h{6epy2mf>Vt-h- zH;axLi*@^T6co#sFm6US9yLv!QQh^V;CWh>qJJ#EiVc1ug_WE7-KlYGbn5Frdzcy8 z^=)G>((2>-aQPG?c|<=kypqmj>AxS}&H>vEk*g?>@RZ?1;W2I&Z#Z@48ZB-z3^aeu zzT1Y|#p~%%t2@hBqmImXM5;Z)OY4Zl^A_Vam*YfmMG3Y zC#jOBxWn7%bBD6J*~cL7S2n-FaiX46YJz7+H_YD78`QfaM zNj|MySqQOVwKC(qPVBH)+F7fEmZWG6FG#U$Kjq+{bC$x+FDQ^>DXQrLq+CnM2rtE! zX=&&@&AY5(%$W8xXHe6%s>BEgo>}B;rA14y&>hL(7u)k`J z8EvH_H>^HiIuoC^mW}egqtp6&+a(%))!LFW&j5B>hZ?w1+-tnY6|KE@vkHY zv0h||6p+%P+sfuXS)JLMK2UrRTWq1dH)7q zMftPas!R81w5(G9k4 zTa7UmAc>VZWhqjFDX975WTJWfaKmWSgyt-AO|Y%9AUmxd#$V6p^M1dd&+~kq@8>;Q zJXG|qJ$Mt4JV4^>K*2IVX$1-|0}uTU6psRn5`gu@_&0zJ#Dx98mN1~5A~M$|AdbAr z`x_y8J_ce#kg_IuuNG247T~-GsYL*yV;)^Qkb9GPtPcg56+lqwM?u|kK;4IRSsxIu zpwMy&SdflF&tHHe4~4sV9_zy9W)isK@qFc5B)*TW4Gsz)z~0$>z?hAF@69#t!APYS zFgatgPY#gy;yh}$n8wfvz%mvSPDllk!@8wg+7N`*tIJ>62E+{Oc8kM+c}RCgHBi7= z-S9O4Nvn0kH+~~F>f_%3ij$qyXGfa=xm@pG;G$zUL|MO|lbS@=y7R0n5&L&afT3OV zL`meB6rXgS2?NnEiE(6ZA^K&$`+8f^@*f#_B!k z)Q5K|Xp{80wGv24l_FU+#P!m|Fda#WO23R#u*GH2cau12$nf+xFHw-sP+vr+%#vZ3 zfrR?w^O)Fd7`6XQX99*>8JFqQxN*&M!D36lOb`6f;Sx<5=uN@Lk?zr*G+wfZ7p?KMvio#dPNIu7XKf+5S>gUpmf%h9#X zz(R|qr-`~9eU`r5fB53Jtu~1=7GJl9RGD%bt=&HmllNGs`{M_4$+s5%Bxqo zG4?5?>0mF ConfUtil - + Bad Include IP address: %1 Некорректный IP адрес для включения: %1 - + Bad Exclude IP address: %1 Некорректный IP адрес для исключения: %1 - - Size of configuration is too big - Конфигурация слишком большая + + Too many IP addresses + Слишком много IP адресов - + + Too many application paths + Слишком много путей приложений + + + Number of Application Groups must be < %1 Количество групп приложений должно быть < %1 - + Length of Application Group's Name must be < %1 Длина наименования группы приложения должна быть < %1 - + Length of Application's Path must be < %1 Длина пути приложения должна быть < %1 @@ -103,33 +108,33 @@ Ip4Range - + Error at line %1: %2 Ошибка в строке %1: %2 - + Bad format Некорректный формат - + Bad IP address Некорректный IP адрес - + Bad second IP address Некорректный второй IP адрес - + Bad range Некорректный диапазон - - + + Bad mask Некорректная маска diff --git a/src/ui/qml/pages/AddressesPage.qml b/src/ui/qml/pages/AddressesPage.qml index 6f430e71..4506fee9 100644 --- a/src/ui/qml/pages/AddressesPage.qml +++ b/src/ui/qml/pages/AddressesPage.qml @@ -6,6 +6,8 @@ import com.fortfirewall 1.0 BasePage { + property AddressGroup addressGroup: firewallConf.inetAddressGroup + RowLayout { anchors.fill: parent spacing: 10 @@ -13,8 +15,6 @@ BasePage { AddressesColumn { id: includeAddresses - addressGroup: firewallConf.ipInclude - title { text: translationManager.dummyBool && qsTranslate("qml", "Include") @@ -25,13 +25,21 @@ BasePage { text: translationManager.dummyBool && qsTranslate("qml", "Include All") } + + useAll: addressGroup.includeAll + ipText: addressGroup.includeText + + onUseAllToggled: { + addressGroup.includeAll = checked; + } + onIpTextEdited: { + addressGroup.includeText = ipText; + } } AddressesColumn { id: excludeAddresses - addressGroup: firewallConf.ipExclude - title { text: translationManager.dummyBool && qsTranslate("qml", "Exclude") @@ -42,6 +50,16 @@ BasePage { text: translationManager.dummyBool && qsTranslate("qml", "Exclude All") } + + useAll: addressGroup.excludeAll + ipText: addressGroup.excludeText + + onUseAllToggled: { + addressGroup.excludeAll = checked; + } + onIpTextEdited: { + addressGroup.excludeText = ipText; + } } } } diff --git a/src/ui/qml/pages/addresses/AddressesColumn.qml b/src/ui/qml/pages/addresses/AddressesColumn.qml index 0142311d..2ae83b58 100644 --- a/src/ui/qml/pages/addresses/AddressesColumn.qml +++ b/src/ui/qml/pages/addresses/AddressesColumn.qml @@ -9,10 +9,14 @@ ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true + signal useAllToggled(bool checked) + signal ipTextEdited(string ipText) + readonly property alias title: title readonly property alias checkBoxAll: checkBoxAll - property AddressGroup addressGroup + property bool useAll + property string ipText RowLayout { Label { @@ -22,9 +26,9 @@ ColumnLayout { } CheckBox { id: checkBoxAll - checked: addressGroup.useAll + checked: useAll onToggled: { - addressGroup.useAll = checked; + useAllToggled(checked); setConfFlagsEdited(); } @@ -37,14 +41,14 @@ ColumnLayout { textArea { placeholderText: netUtil.localIpv4Networks().join('\n') - text: addressGroup.text + text: ipText } onTextChanged: { - if (addressGroup.text == textArea.text) + if (ipText === textArea.text) return; - addressGroup.text = textArea.text; + ipTextEdited(textArea.text); setConfEdited(); } diff --git a/src/ui/task/tasktasix.cpp b/src/ui/task/tasktasix.cpp index d859dceb..541e29fb 100644 --- a/src/ui/task/tasktasix.cpp +++ b/src/ui/task/tasktasix.cpp @@ -36,12 +36,12 @@ bool TaskTasix::processResult(FortManager *fortManager) { #ifndef TASK_TEST FirewallConf *conf = fortManager->firewallConf(); - AddressGroup *ipExclude = conf->ipExclude(); + AddressGroup *inetGroup = conf->inetAddressGroup(); - if (ipExclude->text() == m_rangeText) + if (inetGroup->excludeText() == m_rangeText) return false; - ipExclude->setText(m_rangeText); + inetGroup->setExcludeText(m_rangeText); return fortManager->saveOriginConf(successMessage()); #else diff --git a/src/ui/util/conf/addressrange.cpp b/src/ui/util/conf/addressrange.cpp new file mode 100644 index 00000000..35859134 --- /dev/null +++ b/src/ui/util/conf/addressrange.cpp @@ -0,0 +1,7 @@ +#include "addressrange.h" + +AddressRange::AddressRange() : + m_includeAll(false), + m_excludeAll(false) +{ +} diff --git a/src/ui/util/conf/addressrange.h b/src/ui/util/conf/addressrange.h new file mode 100644 index 00000000..84a7ecae --- /dev/null +++ b/src/ui/util/conf/addressrange.h @@ -0,0 +1,34 @@ +#ifndef ADDRESSRANGE_H +#define ADDRESSRANGE_H + +#include +#include + +#include "../net/ip4range.h" + +class AddressRange +{ +public: + explicit AddressRange(); + + bool includeAll() const { return m_includeAll; } + void setIncludeAll(bool includeAll) { m_includeAll = includeAll; } + + bool excludeAll() const { return m_excludeAll; } + void setExcludeAll(bool excludeAll) { m_excludeAll = excludeAll; } + + Ip4Range &includeRange() { return m_includeRange; } + Ip4Range &excludeRange() { return m_excludeRange; } + + const Ip4Range &includeRange() const { return m_includeRange; } + const Ip4Range &excludeRange() const { return m_excludeRange; } + +private: + uint m_includeAll : 1; + uint m_excludeAll : 1; + + Ip4Range m_includeRange; + Ip4Range m_excludeRange; +}; + +#endif // ADDRESSRANGE_H diff --git a/src/ui/util/confutil.cpp b/src/ui/util/conf/confutil.cpp similarity index 65% rename from src/ui/util/confutil.cpp rename to src/ui/util/conf/confutil.cpp index b942034d..1315a63b 100644 --- a/src/ui/util/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -5,15 +5,16 @@ #define UCHAR quint8 #define UINT16 quint16 #define UINT32 quint32 +#define UINT64 quint64 -#include "../common/fortconf.h" -#include "../common/version.h" -#include "../conf/addressgroup.h" -#include "../conf/appgroup.h" -#include "../conf/firewallconf.h" -#include "../fortcommon.h" -#include "fileutil.h" -#include "net/ip4range.h" +#include "../../common/fortconf.h" +#include "../../common/version.h" +#include "../../conf/addressgroup.h" +#include "../../conf/appgroup.h" +#include "../../conf/firewallconf.h" +#include "../../fortcommon.h" +#include "../fileutil.h" +#include "../net/ip4range.h" #define APP_GROUP_MAX FORT_CONF_GROUP_MAX #define APP_GROUP_NAME_MAX 128 @@ -34,23 +35,17 @@ void ConfUtil::setErrorMessage(const QString &errorMessage) int ConfUtil::write(const FirewallConf &conf, QByteArray &buf) { - Ip4Range incRange; - if (!incRange.fromText(conf.ipInclude()->text())) { - setErrorMessage(tr("Bad Include IP address: %1") - .arg(incRange.errorLineAndMessage())); - return false; - } + quint32 addressGroupsSize = 0; + numbers_arr_t addressGroupOffsets; + addrranges_arr_t addressRanges(conf.addressGroupsList().size()); - Ip4Range excRange; - if (!excRange.fromText(conf.ipExclude()->text())) { - setErrorMessage(tr("Bad Exclude IP address: %1") - .arg(excRange.errorLineAndMessage())); + if (!parseAddressGroups(conf.addressGroupsList(), addressRanges, + addressGroupOffsets, addressGroupsSize)) return false; - } - int appPathsLen = 0; + quint32 appPathsLen = 0; QStringList appPaths; - appperms_arr_t appPerms; + numbers_arr_t appPerms; appgroups_map_t appGroupIndexes; if (!parseAppGroups(conf.appGroupsList(), @@ -58,17 +53,14 @@ int ConfUtil::write(const FirewallConf &conf, QByteArray &buf) appPerms, appGroupIndexes)) return false; - // Calculate maximum required buffer size - if (incRange.size() > FORT_CONF_IP_MAX - || excRange.size() > FORT_CONF_IP_MAX - || appPathsLen > FORT_CONF_APPS_LEN_MAX) { - setErrorMessage(tr("Size of configuration is too big")); + if (appPathsLen > FORT_CONF_APPS_LEN_MAX) { + setErrorMessage(tr("Too many application paths")); return false; } // Fill the buffer const int confIoSize = FORT_CONF_IO_CONF_OFF + FORT_CONF_DATA_OFF - + (incRange.size() + excRange.size()) * 2 * sizeof(quint32) + + addressGroupsSize + FORT_CONF_STR_DATA_SIZE(appGroupIndexes.size()) + appPaths.size() * sizeof(quint32) + FORT_CONF_STR_HEADER_SIZE(appPaths.size()) @@ -77,8 +69,8 @@ int ConfUtil::write(const FirewallConf &conf, QByteArray &buf) buf.reserve(confIoSize); writeData(buf.data(), conf, - incRange, excRange, appPaths, - appPerms, appGroupIndexes); + addressRanges, addressGroupOffsets, + appPaths, appPerms, appGroupIndexes); return confIoSize; } @@ -96,8 +88,6 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf) confFlags->filter_enabled = conf.filterEnabled(); confFlags->stop_traffic = conf.stopTraffic(); confFlags->stop_inet_traffic = conf.stopInetTraffic(); - confFlags->ip_include_all = conf.ipInclude()->useAll(); - confFlags->ip_exclude_all = conf.ipExclude()->useAll(); confFlags->app_block_all = conf.appBlockAll(); confFlags->app_allow_all = conf.appAllowAll(); confFlags->log_blocked = conf.logBlocked(); @@ -107,10 +97,61 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf) return flagsSize; } +bool ConfUtil::parseAddressGroups(const QList &addressGroups, + addrranges_arr_t &addressRanges, + numbers_arr_t &addressGroupOffsets, + quint32 &addressGroupsSize) +{ + const int groupsCount = addressGroups.size(); + + addressGroupsSize = groupsCount * sizeof(quint32); // offsets + + for (int i = 0; i < groupsCount; ++i) { + AddressGroup *addressGroup = addressGroups.at(i); + + AddressRange &addressRange = addressRanges[i]; + addressRange.setIncludeAll(addressGroup->includeAll()); + addressRange.setExcludeAll(addressGroup->excludeAll()); + + if (!addressRange.includeRange() + .fromText(addressGroup->includeText())) { + setErrorMessage(tr("Bad Include IP address: %1") + .arg(addressRange.includeRange() + .errorLineAndMessage())); + return false; + } + + if (!addressRange.excludeRange() + .fromText(addressGroup->excludeText())) { + setErrorMessage(tr("Bad Exclude IP address: %1") + .arg(addressRange.excludeRange() + .errorLineAndMessage())); + return false; + } + + const int incRangeSize = addressRange.includeRange().size(); + const int excRangeSize = addressRange.excludeRange().size(); + + if (incRangeSize > FORT_CONF_IP_MAX + || excRangeSize > FORT_CONF_IP_MAX) { + setErrorMessage(tr("Too many IP addresses")); + return false; + } + + addressGroupOffsets.append(addressGroupsSize); + + addressGroupsSize += FORT_CONF_ADDR_DATA_OFF + + FORT_CONF_IP_RANGE_SIZE(incRangeSize) + + FORT_CONF_IP_RANGE_SIZE(excRangeSize); + } + + return true; +} + bool ConfUtil::parseAppGroups(const QList &appGroups, QStringList &appPaths, - int &appPathsLen, - appperms_arr_t &appPerms, + quint32 &appPathsLen, + numbers_arr_t &appPerms, appgroups_map_t &appGroupIndexes) { const int groupsCount = appGroups.size(); @@ -213,33 +254,23 @@ QString ConfUtil::parseAppPath(const QStringRef &line) } void ConfUtil::writeData(char *output, const FirewallConf &conf, - const Ip4Range &incRange, const Ip4Range &excRange, + const addrranges_arr_t &addressRanges, + const numbers_arr_t &addressGroupOffsets, const QStringList &appPaths, - const appperms_arr_t &appPerms, + const numbers_arr_t &appPerms, const appgroups_map_t &appGroupIndexes) { PFORT_CONF_IO drvConfIo = (PFORT_CONF_IO) output; PFORT_CONF drvConf = &drvConfIo->conf; - char *data = (char *) &drvConf->data; - const quint32 incRangeSize = incRange.size(); - const quint32 excRangeSize = excRange.size(); + char *data = drvConf->data; const quint32 appPathsSize = appPaths.size(); - quint32 incRangeFromOff, incRangeToOff; - quint32 excRangeFromOff, excRangeToOff; + quint32 addrGroupsOff; quint32 appPathsOff, appPermsOff, appGroupsOff; -#define CONF_DATA_OFFSET (data - (char *) &drvConf->data) - incRangeFromOff = CONF_DATA_OFFSET; - writeNumbers(&data, incRange.fromArray()); - - incRangeToOff = CONF_DATA_OFFSET; - writeNumbers(&data, incRange.toArray()); - - excRangeFromOff = CONF_DATA_OFFSET; - writeNumbers(&data, excRange.fromArray()); - - excRangeToOff = CONF_DATA_OFFSET; - writeNumbers(&data, excRange.toArray()); +#define CONF_DATA_OFFSET (data - drvConf->data) + addrGroupsOff = CONF_DATA_OFFSET; + writeNumbers(&data, addressGroupOffsets); + writeAddressRanges(&data, addressRanges); appGroupsOff = CONF_DATA_OFFSET; writeChars(&data, appGroupIndexes.values().toVector()); @@ -261,9 +292,6 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf, drvConf->flags.stop_traffic = conf.stopTraffic(); drvConf->flags.stop_inet_traffic = conf.stopInetTraffic(); - drvConf->flags.ip_include_all = conf.ipInclude()->useAll(); - drvConf->flags.ip_exclude_all = conf.ipExclude()->useAll(); - drvConf->flags.app_block_all = conf.appBlockAll(); drvConf->flags.app_allow_all = conf.appAllowAll(); @@ -274,18 +302,9 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf, FortCommon::confAppPermsMaskInit(drvConf); - drvConf->data_off = FORT_CONF_DATA_OFF; - - drvConf->ip_include_n = incRangeSize; - drvConf->ip_exclude_n = excRangeSize; - drvConf->apps_n = appPathsSize; - drvConf->ip_from_include_off = incRangeFromOff; - drvConf->ip_to_include_off = incRangeToOff; - - drvConf->ip_from_exclude_off = excRangeFromOff; - drvConf->ip_to_exclude_off = excRangeToOff; + drvConf->addr_groups_off = addrGroupsOff; drvConf->app_groups_off = appGroupsOff; drvConf->app_perms_off = appPermsOff; @@ -316,6 +335,38 @@ quint16 ConfUtil::writeLimits(struct fort_conf_limit *limits, return limitBits; } +void ConfUtil::writeAddressRanges(char **data, + const addrranges_arr_t &addressRanges) +{ + const int rangesCount = addressRanges.size(); + + for (int i = 0; i < rangesCount; ++i) { + const AddressRange &addressRange = addressRanges[i]; + + 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_n = addressRange.includeRange().fromArray().size(); + addrGroup->exclude_n = addressRange.excludeRange().fromArray().size(); + + *data += FORT_CONF_ADDR_DATA_OFF; + + writeNumbers(data, addressRange.includeRange().fromArray()); + writeNumbers(data, addressRange.includeRange().toArray()); + + writeNumbers(data, addressRange.excludeRange().fromArray()); + writeNumbers(data, addressRange.excludeRange().toArray()); +} + void ConfUtil::writeNumbers(char **data, const QVector &array) { const int arraySize = array.size() * sizeof(quint32); diff --git a/src/ui/util/confutil.h b/src/ui/util/conf/confutil.h similarity index 66% rename from src/ui/util/confutil.h rename to src/ui/util/conf/confutil.h index 22eca6c6..5592090b 100644 --- a/src/ui/util/confutil.h +++ b/src/ui/util/conf/confutil.h @@ -7,14 +7,19 @@ #include #include +#include "addressrange.h" + +QT_FORWARD_DECLARE_CLASS(AddressGroup) QT_FORWARD_DECLARE_CLASS(AppGroup) QT_FORWARD_DECLARE_CLASS(FirewallConf) -QT_FORWARD_DECLARE_CLASS(Ip4Range) QT_FORWARD_DECLARE_STRUCT(fort_conf_limit) +typedef QVector numbers_arr_t; + +typedef QVarLengthArray addrranges_arr_t; + typedef QMap appperms_map_t; -typedef QVector appperms_arr_t; typedef QMap appgroups_map_t; class ConfUtil : public QObject @@ -37,11 +42,16 @@ public slots: private: void setErrorMessage(const QString &errorMessage); + bool parseAddressGroups(const QList &addressGroups, + addrranges_arr_t &addressRanges, + numbers_arr_t &addressGroupOffsets, + quint32 &addressGroupsSize); + // Convert app. groups to plain lists bool parseAppGroups(const QList &appGroups, QStringList &appPaths, - int &appPathsLen, - appperms_arr_t &appPerms, + quint32 &appPathsLen, + numbers_arr_t &appPerms, appgroups_map_t &appGroupIndexes); bool parseApps(const QString &text, bool blocked, @@ -52,14 +62,20 @@ private: static QString parseAppPath(const QStringRef &line); static void writeData(char *output, const FirewallConf &conf, - const Ip4Range &incRange, const Ip4Range &excRange, + const addrranges_arr_t &addressRanges, + const numbers_arr_t &addressGroupOffsets, const QStringList &appPaths, - const appperms_arr_t &appPerms, + const numbers_arr_t &appPerms, const appgroups_map_t &appGroupIndexes); static quint16 writeLimits(struct fort_conf_limit *limits, const QList &appGroups); + static void writeAddressRanges(char **data, + const addrranges_arr_t &addressRanges); + static void writeAddressRange(char **data, + const AddressRange &addressRange); + static void writeNumbers(char **data, const QVector &array); static void writeChars(char **data, const QVector &array); static void writeStrings(char **data, const QStringList &list); diff --git a/src/ui/util/net/ip4range.cpp b/src/ui/util/net/ip4range.cpp index de1a3bd5..0d23b411 100644 --- a/src/ui/util/net/ip4range.cpp +++ b/src/ui/util/net/ip4range.cpp @@ -11,6 +11,15 @@ Ip4Range::Ip4Range(QObject *parent) : { } +void Ip4Range::clear() +{ + m_errorLineNo = 0; + m_errorMessage = QString(); + + m_fromArray.clear(); + m_toArray.clear(); +} + void Ip4Range::setErrorLineNo(int lineNo) { if (m_errorLineNo != lineNo) { @@ -52,8 +61,7 @@ QString Ip4Range::toText() bool Ip4Range::fromText(const QString &text) { - m_fromArray.clear(); - m_toArray.clear(); + clear(); ip4range_map_t ipRangeMap; diff --git a/src/ui/util/net/ip4range.h b/src/ui/util/net/ip4range.h index b3f8c72f..211283ff 100644 --- a/src/ui/util/net/ip4range.h +++ b/src/ui/util/net/ip4range.h @@ -40,6 +40,8 @@ signals: void errorMessageChanged(); public slots: + void clear(); + QString toText(); // Parse IPv4 ranges from text