Add ability to use more IPv4 Address Groups.

This commit is contained in:
Nodir Temirkhodjaev 2018-01-20 13:57:22 +05:00
parent e42c0c0be0
commit 8c468aaa69
29 changed files with 516 additions and 244 deletions

View File

@ -15,8 +15,7 @@ fort_memcmp (const char *p1, const char *p2, size_t len)
#endif #endif
static BOOL static BOOL
fort_conf_ip_inrange (UINT32 ip, UINT32 count, fort_conf_ip_inrange (UINT32 ip, UINT32 count, const UINT32 *iprange)
const UINT32 *iprange_from, const UINT32 *iprange_to)
{ {
int low, high; int low, high;
@ -27,7 +26,7 @@ fort_conf_ip_inrange (UINT32 ip, UINT32 count,
do { do {
const int mid = (low + high) / 2; const int mid = (low + high) / 2;
const UINT32 mid_ip = iprange_from[mid]; const UINT32 mid_ip = iprange[mid];
if (ip < mid_ip) if (ip < mid_ip)
high = mid - 1; high = mid - 1;
@ -37,32 +36,56 @@ fort_conf_ip_inrange (UINT32 ip, UINT32 count,
return TRUE; return TRUE;
} while (low <= high); } 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 static const PFORT_CONF_ADDR_GROUP
fort_conf_ip_included (const PFORT_CONF conf, UINT32 remote_ip) 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; return (PFORT_CONF_ADDR_GROUP)
const BOOL exclude_all = conf->flags.ip_exclude_all; (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 const BOOL ip_included = include_all ? TRUE
: fort_conf_ip_inrange(remote_ip, conf->ip_include_n, : fort_conf_ip_inrange(remote_ip, addr_group->include_n,
(const UINT32 *) (data + conf->ip_from_include_off), fort_conf_addr_group_include_ref(addr_group));
(const UINT32 *) (data + conf->ip_to_include_off));
const BOOL ip_excluded = exclude_all ? TRUE const BOOL ip_excluded = exclude_all ? TRUE
: fort_conf_ip_inrange(remote_ip, conf->ip_exclude_n, : fort_conf_ip_inrange(remote_ip, addr_group->exclude_n,
(const UINT32 *) (data + conf->ip_from_exclude_off), fort_conf_addr_group_exclude_ref(addr_group));
(const UINT32 *) (data + conf->ip_to_exclude_off));
return include_all ? !ip_excluded return include_all ? !ip_excluded
: (exclude_all ? ip_included : (exclude_all ? ip_included
: (ip_included && !ip_excluded)); : (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 static int
fort_conf_app_cmp (UINT32 path_len, const char *path, fort_conf_app_cmp (UINT32 path_len, const char *path,
const char *apps, const UINT32 *app_offp) const char *apps, const UINT32 *app_offp)
@ -90,7 +113,7 @@ fort_conf_app_index (const PFORT_CONF conf,
if (count == 0) if (count == 0)
return -1; return -1;
data = (const char *) conf + conf->data_off; data = conf->data;
app_offsets = (const UINT32 *) (data + conf->apps_off); app_offsets = (const UINT32 *) (data + conf->apps_off);
apps = (const char *) (app_offsets + count + 1); apps = (const char *) (app_offsets + count + 1);
@ -115,7 +138,7 @@ fort_conf_app_index (const PFORT_CONF conf,
static UCHAR static UCHAR
fort_conf_app_group_index (const PFORT_CONF conf, int app_index) 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 UCHAR *app_groups = (const UCHAR *) (data + conf->app_groups_off);
const BOOL app_found = (app_index != -1); 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 static BOOL
fort_conf_app_blocked (const PFORT_CONF conf, int app_index) 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); const UINT32 *app_perms = (const UINT32 *) (data + conf->app_perms_off);

View File

@ -1,7 +1,8 @@
#ifndef FORTCONF_H #ifndef FORTCONF_H
#define 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_GROUP_MAX 16
#define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024) #define FORT_CONF_APPS_LEN_MAX (64 * 1024 * 1024)
#define FORT_CONF_APP_PATH_MAX (2 * 1024) #define FORT_CONF_APP_PATH_MAX (2 * 1024)
@ -14,16 +15,24 @@ typedef struct fort_conf_flags {
UINT32 filter_enabled : 1; UINT32 filter_enabled : 1;
UINT32 stop_traffic : 1; UINT32 stop_traffic : 1;
UINT32 stop_inet_traffic : 1; UINT32 stop_inet_traffic : 1;
UINT32 ip_include_all : 1;
UINT32 ip_exclude_all : 1;
UINT32 app_block_all : 1; UINT32 app_block_all : 1;
UINT32 app_allow_all : 1; UINT32 app_allow_all : 1;
UINT32 log_blocked : 1; UINT32 log_blocked : 1;
UINT32 log_stat : 1; UINT32 log_stat : 1;
UINT32 _reserved_ : 7; UINT32 _reserved_ : 9;
UINT32 group_bits : 16; UINT32 group_bits : 16;
} FORT_CONF_FLAGS, *PFORT_CONF_FLAGS; } 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 { typedef struct fort_conf_limit {
/* Bytes per 0.5 sec. */ /* Bytes per 0.5 sec. */
UINT32 in_bytes; UINT32 in_bytes;
@ -33,27 +42,18 @@ typedef struct fort_conf_limit {
typedef struct fort_conf { typedef struct fort_conf {
FORT_CONF_FLAGS flags; FORT_CONF_FLAGS flags;
UINT16 data_off;
UINT16 ip_include_n;
UINT16 ip_exclude_n;
UINT16 apps_n; UINT16 apps_n;
UINT32 app_perms_block_mask; UINT32 app_perms_block_mask;
UINT32 app_perms_allow_mask; UINT32 app_perms_allow_mask;
UINT32 ip_from_include_off; UINT32 addr_groups_off;
UINT32 ip_to_include_off;
UINT32 ip_from_exclude_off;
UINT32 ip_to_exclude_off;
UINT32 app_groups_off; UINT32 app_groups_off;
UINT32 app_perms_off; UINT32 app_perms_off;
UINT32 apps_off; UINT32 apps_off;
UCHAR data[4]; char data[4];
} FORT_CONF, *PFORT_CONF; } FORT_CONF, *PFORT_CONF;
typedef struct fort_conf_io { 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_DATA_OFF offsetof(FORT_CONF, data)
#define FORT_CONF_IO_CONF_OFF offsetof(FORT_CONF_IO, conf) #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 #endif FORTCONF_H

View File

@ -7,6 +7,6 @@
#define APP_UPDATES_URL "https://github.com/tnodir/fort/releases" #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 APP_UPDATES_API_URL "https://api.github.com/repos/tnodir/fort/releases/latest"
#define DRIVER_VERSION 4 #define DRIVER_VERSION 5
#endif // VERSION_H #endif // VERSION_H

View File

@ -214,14 +214,12 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
int flagsField, int remoteIpField) int flagsField, int remoteIpField)
{ {
PFORT_CONF_REF conf_ref; PFORT_CONF_REF conf_ref;
PVOID path;
FORT_CONF_FLAGS conf_flags; FORT_CONF_FLAGS conf_flags;
UINT32 flags; UINT32 flags;
UINT32 remote_ip; UINT32 remote_ip;
UINT32 process_id; UINT32 process_id;
UINT32 path_len; UINT32 path_len;
PVOID path;
int app_index;
BOOL ip_included, blocked;
PIRP irp = NULL; PIRP irp = NULL;
ULONG_PTR info; ULONG_PTR info;
@ -252,42 +250,41 @@ fort_callout_classify_v4 (const FWPS_INCOMING_VALUES0 *inFixedValues,
if (conf_flags.stop_traffic) if (conf_flags.stop_traffic)
goto block; goto block;
if (!conf_flags.filter_enabled) if (!conf_flags.filter_enabled
|| !fort_conf_ip_is_inet(&conf_ref->conf, remote_ip))
goto permit; goto permit;
ip_included = fort_conf_ip_included(&conf_ref->conf, remote_ip); if (conf_flags.stop_inet_traffic)
if (ip_included && conf_flags.stop_inet_traffic)
goto block; goto block;
process_id = (UINT32) inMetaValues->processId; process_id = (UINT32) inMetaValues->processId;
path_len = inMetaValues->processPath->size - sizeof(WCHAR); // chop terminating zero path_len = inMetaValues->processPath->size - sizeof(WCHAR); // chop terminating zero
path = inMetaValues->processPath->data; path = inMetaValues->processPath->data;
blocked = ip_included if (fort_conf_ip_inet_included(&conf_ref->conf, remote_ip)) {
&& ((app_index = fort_conf_app_index(&conf_ref->conf, path_len, path)), const int app_index = fort_conf_app_index(&conf_ref->conf, path_len, path);
fort_conf_app_blocked(&conf_ref->conf, app_index));
if (!blocked) { if (!fort_conf_app_blocked(&conf_ref->conf, app_index)) {
if (ip_included && conf_flags.log_stat) { if (conf_flags.log_stat) {
const UINT64 flowId = inMetaValues->flowHandle; const UINT64 flowId = inMetaValues->flowHandle;
const UCHAR group_index = fort_conf_app_group_index( const UCHAR group_index = fort_conf_app_group_index(
&conf_ref->conf, app_index); &conf_ref->conf, app_index);
BOOL is_new_proc = FALSE; BOOL is_new_proc = FALSE;
NTSTATUS status; NTSTATUS status;
status = fort_stat_flow_associate(&g_device->stat, status = fort_stat_flow_associate(&g_device->stat,
flowId, process_id, group_index, &is_new_proc); flowId, process_id, group_index, &is_new_proc);
if (!NT_SUCCESS(status)) { if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: Classify v4: Flow assoc. error: %d\n", status); "FORT: Classify v4: Flow assoc. error: %d\n", status);
} else if (is_new_proc) { } else if (is_new_proc) {
fort_buffer_proc_new_write(&g_device->buffer, fort_buffer_proc_new_write(&g_device->buffer,
process_id, path_len, path, &irp, &info); process_id, path_len, path, &irp, &info);
}
} }
goto permit;
} }
goto permit;
} }
if (conf_flags.log_blocked) { if (conf_flags.log_blocked) {

View File

@ -5,7 +5,8 @@ SOURCES += \
$$UIPATH/conf/appgroup.cpp \ $$UIPATH/conf/appgroup.cpp \
$$UIPATH/conf/firewallconf.cpp \ $$UIPATH/conf/firewallconf.cpp \
$$UIPATH/fortcommon.cpp \ $$UIPATH/fortcommon.cpp \
$$UIPATH/util/confutil.cpp \ $$UIPATH/util/conf/addressrange.cpp \
$$UIPATH/util/conf/confutil.cpp \
$$UIPATH/util/fileutil.cpp \ $$UIPATH/util/fileutil.cpp \
$$UIPATH/util/net/ip4range.cpp \ $$UIPATH/util/net/ip4range.cpp \
$$UIPATH/util/net/netutil.cpp $$UIPATH/util/net/netutil.cpp
@ -15,7 +16,8 @@ HEADERS += \
$$UIPATH/conf/appgroup.h \ $$UIPATH/conf/appgroup.h \
$$UIPATH/conf/firewallconf.h \ $$UIPATH/conf/firewallconf.h \
$$UIPATH/fortcommon.h \ $$UIPATH/fortcommon.h \
$$UIPATH/util/confutil.h \ $$UIPATH/util/conf/addressrange.h \
$$UIPATH/util/conf/confutil.h \
$$UIPATH/util/fileutil.h \ $$UIPATH/util/fileutil.h \
$$UIPATH/util/net/ip4range.h \ $$UIPATH/util/net/ip4range.h \
$$UIPATH/util/net/netutil.h $$UIPATH/util/net/netutil.h

View File

@ -6,7 +6,7 @@
#include "conf/appgroup.h" #include "conf/appgroup.h"
#include "conf/firewallconf.h" #include "conf/firewallconf.h"
#include "fortcommon.h" #include "fortcommon.h"
#include "util/confutil.h" #include "util/conf/confutil.h"
#include "util/fileutil.h" #include "util/fileutil.h"
#include "util/net/netutil.h" #include "util/net/netutil.h"
@ -14,21 +14,19 @@ void Test::confWriteRead()
{ {
FirewallConf conf; FirewallConf conf;
conf.ipInclude()->setUseAll(true); AddressGroup *inetGroup = conf.inetAddressGroup();
conf.ipExclude()->setUseAll(false);
inetGroup->setIncludeAll(true);
inetGroup->setExcludeAll(false);
inetGroup->setIncludeText(QString());
inetGroup->setExcludeText(
NetUtil::localIpv4Networks().join('\n')
);
conf.setAppBlockAll(true); conf.setAppBlockAll(true);
conf.setAppAllowAll(false); 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(); AppGroup *appGroup1 = new AppGroup();
appGroup1->setName("Base"); appGroup1->setName("Base");
appGroup1->setEnabled(true); appGroup1->setEnabled(true);

View File

@ -10,7 +10,8 @@ SOURCES += \
$$UIPATH/log/logentryblocked.cpp \ $$UIPATH/log/logentryblocked.cpp \
$$UIPATH/log/logentryprocnew.cpp \ $$UIPATH/log/logentryprocnew.cpp \
$$UIPATH/log/logentrystattraf.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/device.cpp \
$$UIPATH/util/fileutil.cpp \ $$UIPATH/util/fileutil.cpp \
$$UIPATH/util/net/ip4range.cpp \ $$UIPATH/util/net/ip4range.cpp \
@ -28,7 +29,8 @@ HEADERS += \
$$UIPATH/log/logentryblocked.h \ $$UIPATH/log/logentryblocked.h \
$$UIPATH/log/logentryprocnew.h \ $$UIPATH/log/logentryprocnew.h \
$$UIPATH/log/logentrystattraf.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/device.h \
$$UIPATH/util/fileutil.h \ $$UIPATH/util/fileutil.h \
$$UIPATH/util/net/ip4range.h \ $$UIPATH/util/net/ip4range.h \

View File

@ -10,7 +10,7 @@
#include "fortcommon.h" #include "fortcommon.h"
#include "log/logbuffer.h" #include "log/logbuffer.h"
#include "log/logentryblocked.h" #include "log/logentryblocked.h"
#include "util/confutil.h" #include "util/conf/confutil.h"
#include "util/device.h" #include "util/device.h"
#include "util/fileutil.h" #include "util/fileutil.h"
#include "util/net/netutil.h" #include "util/net/netutil.h"
@ -42,22 +42,20 @@ void Test::setConf(Device &device)
conf.setProvBoot(true); conf.setProvBoot(true);
conf.ipInclude()->setUseAll(true); AddressGroup *inetGroup = conf.inetAddressGroup();
conf.ipExclude()->setUseAll(false);
inetGroup->setIncludeAll(true);
inetGroup->setExcludeAll(false);
inetGroup->setExcludeText(
NetUtil::localIpv4Networks().join('\n')
);
conf.setAppBlockAll(true); conf.setAppBlockAll(true);
conf.setAppAllowAll(false); conf.setAppAllowAll(false);
conf.setLogBlocked(true); 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; ConfUtil confUtil;
QByteArray buf; QByteArray buf;

View File

@ -41,7 +41,8 @@ SOURCES += \
task/taskuzonline.cpp \ task/taskuzonline.cpp \
task/taskworker.cpp \ task/taskworker.cpp \
translationmanager.cpp \ translationmanager.cpp \
util/confutil.cpp \ util/conf/addressrange.cpp \
util/conf/confutil.cpp \
util/dateutil.cpp \ util/dateutil.cpp \
util/device.cpp \ util/device.cpp \
util/fileutil.cpp \ util/fileutil.cpp \
@ -89,7 +90,8 @@ HEADERS += \
task/taskuzonline.h \ task/taskuzonline.h \
task/taskworker.h \ task/taskworker.h \
translationmanager.h \ translationmanager.h \
util/confutil.h \ util/conf/addressrange.h \
util/conf/confutil.h \
util/dateutil.h \ util/dateutil.h \
util/device.h \ util/device.h \
util/fileutil.h \ util/fileutil.h \

View File

@ -2,23 +2,40 @@
AddressGroup::AddressGroup(QObject *parent) : AddressGroup::AddressGroup(QObject *parent) :
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) { if (m_includeAll != includeAll) {
m_useAll = useAll; m_includeAll = includeAll;
emit useAllChanged(); emit includeAllChanged();
} }
} }
void AddressGroup::setText(const QString &text) void AddressGroup::setExcludeAll(bool excludeAll)
{ {
if (m_text != text) { if (m_excludeAll != excludeAll) {
m_text = text; m_excludeAll = excludeAll;
emit textChanged(); 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; QVariantMap map;
map["text"] = text(); map["includeAll"] = includeAll();
map["excludeAll"] = excludeAll();
map["includeText"] = includeText();
map["excludeText"] = excludeText();
return map; return map;
} }
@ -35,5 +56,9 @@ void AddressGroup::fromVariant(const QVariant &v)
{ {
const QVariantMap map = v.toMap(); 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();
} }

View File

@ -7,31 +7,43 @@
class AddressGroup : public QObject class AddressGroup : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool useAll READ useAll WRITE setUseAll NOTIFY useAllChanged) Q_PROPERTY(bool includeAll READ includeAll WRITE setIncludeAll NOTIFY includeAllChanged)
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) 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: public:
explicit AddressGroup(QObject *parent = nullptr); explicit AddressGroup(QObject *parent = nullptr);
bool useAll() const { return m_useAll; } bool includeAll() const { return m_includeAll; }
void setUseAll(bool useAll); void setIncludeAll(bool includeAll);
QString text() const { return m_text; } bool excludeAll() const { return m_excludeAll; }
void setText(const QString &text); 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; QVariant toVariant() const;
void fromVariant(const QVariant &v); void fromVariant(const QVariant &v);
signals: signals:
void useAllChanged(); void includeAllChanged();
void textChanged(); void excludeAllChanged();
void includeTextChanged();
void excludeTextChanged();
public slots: public slots:
private: 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 #endif // ADDRESSGROUP_H

View File

@ -22,10 +22,10 @@ FirewallConf::FirewallConf(QObject *parent) :
m_trafHourKeepDays(DEFAULT_TRAF_HOUR_KEEP_DAYS), m_trafHourKeepDays(DEFAULT_TRAF_HOUR_KEEP_DAYS),
m_trafDayKeepDays(DEFAULT_TRAF_DAY_KEEP_DAYS), m_trafDayKeepDays(DEFAULT_TRAF_DAY_KEEP_DAYS),
m_trafMonthKeepMonths(DEFAULT_TRAF_MONTH_KEEP_MONTHS), m_trafMonthKeepMonths(DEFAULT_TRAF_MONTH_KEEP_MONTHS),
m_trafUnit(UnitAdaptive), m_trafUnit(UnitAdaptive)
m_ipInclude(new AddressGroup(this)),
m_ipExclude(new AddressGroup(this))
{ {
m_addressGroups.append(new AddressGroup(this));
m_addressGroups.append(new AddressGroup(this));
} }
void FirewallConf::setProvBoot(bool provBoot) void FirewallConf::setProvBoot(bool provBoot)
@ -178,6 +178,11 @@ void FirewallConf::setAppGroupBits(quint32 groupBits)
} }
} }
QQmlListProperty<AddressGroup> FirewallConf::addressGroups()
{
return QQmlListProperty<AddressGroup>(this, m_addressGroups);
}
QQmlListProperty<AppGroup> FirewallConf::appGroups() QQmlListProperty<AppGroup> FirewallConf::appGroups()
{ {
return QQmlListProperty<AppGroup>(this, m_appGroups); return QQmlListProperty<AppGroup>(this, m_appGroups);
@ -226,8 +231,6 @@ void FirewallConf::copyFlags(const FirewallConf &o)
setStopTraffic(o.stopTraffic()); setStopTraffic(o.stopTraffic());
setStopInetTraffic(o.stopInetTraffic()); setStopInetTraffic(o.stopInetTraffic());
setLogErrors(o.logErrors()); setLogErrors(o.logErrors());
ipInclude()->setUseAll(o.ipInclude()->useAll());
ipExclude()->setUseAll(o.ipExclude()->useAll());
setAppBlockAll(o.appBlockAll()); setAppBlockAll(o.appBlockAll());
setAppAllowAll(o.appAllowAll()); setAppAllowAll(o.appAllowAll());
setPasswordHash(o.passwordHash()); setPasswordHash(o.passwordHash());
@ -255,8 +258,11 @@ QVariant FirewallConf::toVariant() const
map["passwordHash"] = m_passwordHash; map["passwordHash"] = m_passwordHash;
map["ipInclude"] = ipInclude()->toVariant(); QVariantList addresses;
map["ipExclude"] = ipExclude()->toVariant(); foreach (const AddressGroup *addressGroup, addressGroupsList()) {
addresses.append(addressGroup->toVariant());
}
map["addressGroups"] = addresses;
QVariantList groups; QVariantList groups;
foreach (const AppGroup *appGroup, appGroupsList()) { foreach (const AppGroup *appGroup, appGroupsList()) {
@ -273,8 +279,12 @@ void FirewallConf::fromVariant(const QVariant &v)
m_passwordHash = map["passwordHash"].toString(); m_passwordHash = map["passwordHash"].toString();
m_ipInclude->fromVariant(map["ipInclude"]); const QVariantList addresses = map["addressGroups"].toList();
m_ipExclude->fromVariant(map["ipExclude"]); int addrGroupIndex = 0;
foreach (const QVariant &av, addresses) {
AddressGroup *addressGroup = m_addressGroups.at(addrGroupIndex++);
addressGroup->fromVariant(av);
}
const QVariantList groups = map["appGroups"].toList(); const QVariantList groups = map["appGroups"].toList();
foreach (const QVariant &gv, groups) { foreach (const QVariant &gv, groups) {
@ -286,8 +296,8 @@ void FirewallConf::fromVariant(const QVariant &v)
void FirewallConf::setupDefault() void FirewallConf::setupDefault()
{ {
m_ipInclude->setUseAll(true); AddressGroup *inetGroup = inetAddressGroup();
m_ipExclude->setText(NetUtil::localIpv4Networks().join('\n')); inetGroup->setExcludeText(NetUtil::localIpv4Networks().join('\n'));
AppGroup *appGroup = new AppGroup(); AppGroup *appGroup = new AppGroup();
appGroup->setName("Main"); appGroup->setName("Main");

View File

@ -34,8 +34,8 @@ class FirewallConf : public QObject
Q_PROPERTY(int trafUnit READ trafUnit WRITE setTrafUnit NOTIFY trafUnitChanged) Q_PROPERTY(int trafUnit READ trafUnit WRITE setTrafUnit NOTIFY trafUnitChanged)
Q_PROPERTY(bool hasPassword READ hasPassword NOTIFY passwordHashChanged) Q_PROPERTY(bool hasPassword READ hasPassword NOTIFY passwordHashChanged)
Q_PROPERTY(QString passwordHash READ passwordHash WRITE setPasswordHash NOTIFY passwordHashChanged) Q_PROPERTY(QString passwordHash READ passwordHash WRITE setPasswordHash NOTIFY passwordHashChanged)
Q_PROPERTY(AddressGroup *ipInclude READ ipInclude CONSTANT) Q_PROPERTY(AddressGroup *inetAddressGroup READ inetAddressGroup NOTIFY addressGroupsChanged)
Q_PROPERTY(AddressGroup *ipExclude READ ipExclude CONSTANT) Q_PROPERTY(QQmlListProperty<AddressGroup> addressGroups READ addressGroups NOTIFY addressGroupsChanged)
Q_PROPERTY(QQmlListProperty<AppGroup> appGroups READ appGroups NOTIFY appGroupsChanged) Q_PROPERTY(QQmlListProperty<AppGroup> appGroups READ appGroups NOTIFY appGroupsChanged)
Q_CLASSINFO("DefaultProperty", "appGroups") Q_CLASSINFO("DefaultProperty", "appGroups")
@ -105,8 +105,10 @@ public:
quint32 appGroupBits() const; quint32 appGroupBits() const;
void setAppGroupBits(quint32 groupBits); void setAppGroupBits(quint32 groupBits);
AddressGroup *ipInclude() const { return m_ipInclude; } AddressGroup *inetAddressGroup() const { return m_addressGroups.at(0); }
AddressGroup *ipExclude() const { return m_ipExclude; }
const QList<AddressGroup *> &addressGroupsList() const { return m_addressGroups; }
QQmlListProperty<AddressGroup> addressGroups();
const QList<AppGroup *> &appGroupsList() const { return m_appGroups; } const QList<AppGroup *> &appGroupsList() const { return m_appGroups; }
QQmlListProperty<AppGroup> appGroups(); QQmlListProperty<AppGroup> appGroups();
@ -136,6 +138,7 @@ signals:
void trafMonthKeepMonthsChanged(); void trafMonthKeepMonthsChanged();
void trafUnitChanged(); void trafUnitChanged();
void passwordHashChanged(); void passwordHashChanged();
void addressGroupsChanged();
void appGroupsChanged(); void appGroupsChanged();
public slots: public slots:
@ -169,9 +172,7 @@ private:
QString m_passwordHash; QString m_passwordHash;
AddressGroup *m_ipInclude; QList<AddressGroup *> m_addressGroups;
AddressGroup *m_ipExclude;
QList<AppGroup *> m_appGroups; QList<AppGroup *> m_appGroups;
}; };

View File

@ -5,7 +5,7 @@
#include "../conf/firewallconf.h" #include "../conf/firewallconf.h"
#include "../fortcommon.h" #include "../fortcommon.h"
#include "../log/logbuffer.h" #include "../log/logbuffer.h"
#include "../util/confutil.h" #include "../util/conf/confutil.h"
#include "../util/device.h" #include "../util/device.h"
#include "../util/osutil.h" #include "../util/osutil.h"
#include "driverworker.h" #include "driverworker.h"

View File

@ -131,18 +131,19 @@ void FortCommon::confAppPermsMaskInit(void *drvConf)
} }
bool FortCommon::confIpInRange(const void *drvConf, quint32 ip, bool FortCommon::confIpInRange(const void *drvConf, quint32 ip,
bool included) bool included, int addrGroupIndex)
{ {
const PFORT_CONF conf = (const PFORT_CONF) drvConf; 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 UINT32 count = included ? addr_group->include_n
const quint32 fromOff = included ? conf->ip_from_include_off : conf->ip_from_exclude_off; : addr_group->exclude_n;
const quint32 toOff = included ? conf->ip_to_include_off : conf->ip_to_exclude_off; 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, return fort_conf_ip_inrange(ip, count, iprange);
(const quint32 *) (data + fromOff),
(const quint32 *) (data + toOff));
} }
int FortCommon::confAppIndex(const void *drvConf, int FortCommon::confAppIndex(const void *drvConf,

View File

@ -51,7 +51,7 @@ public:
static void confAppPermsMaskInit(void *drvConf); static void confAppPermsMaskInit(void *drvConf);
static bool confIpInRange(const void *drvConf, quint32 ip, static bool confIpInRange(const void *drvConf, quint32 ip,
bool included = false); bool included = false, int addrGroupIndex = 0);
static int confAppIndex(const void *drvConf, static int confAppIndex(const void *drvConf,
const QString &kernelPath); const QString &kernelPath);
static quint8 confAppGroupIndex(const void *drvConf, int appIndex); static quint8 confAppGroupIndex(const void *drvConf, int appIndex);

View File

@ -160,7 +160,11 @@ bool FortSettings::tryToReadConf(FirewallConf &conf, const QString &filePath)
return false; return false;
} }
conf.fromVariant(jsonDoc.toVariant()); QVariant confVar = jsonDoc.toVariant();
confVar = migrateConf(confVar);
conf.fromVariant(confVar);
return true; return true;
} }
@ -191,6 +195,8 @@ bool FortSettings::writeConf(const FirewallConf &conf)
return false; return false;
} }
removeMigratedKeys();
return true; return true;
} }
@ -220,8 +226,6 @@ bool FortSettings::readConfIni(FirewallConf &conf) const
conf.setLogErrors(iniBool("logErrors")); conf.setLogErrors(iniBool("logErrors"));
conf.setLogBlocked(iniBool("logBlocked")); conf.setLogBlocked(iniBool("logBlocked"));
conf.setLogStat(iniBool("logStat")); conf.setLogStat(iniBool("logStat"));
conf.ipInclude()->setUseAll(iniBool("ipIncludeAll"));
conf.ipExclude()->setUseAll(iniBool("ipExcludeAll"));
conf.setAppBlockAll(iniBool("appBlockAll", true)); conf.setAppBlockAll(iniBool("appBlockAll", true));
conf.setAppAllowAll(iniBool("appAllowAll")); conf.setAppAllowAll(iniBool("appAllowAll"));
conf.setAppGroupBits(iniUInt("appGroupBits", DEFAULT_APP_GROUP_BITS)); conf.setAppGroupBits(iniUInt("appGroupBits", DEFAULT_APP_GROUP_BITS));
@ -249,8 +253,6 @@ bool FortSettings::writeConfIni(const FirewallConf &conf)
setIniValue("logErrors", conf.logErrors()); setIniValue("logErrors", conf.logErrors());
setIniValue("logBlocked", conf.logBlocked()); setIniValue("logBlocked", conf.logBlocked());
setIniValue("logStat", conf.logStat()); setIniValue("logStat", conf.logStat());
setIniValue("ipIncludeAll", conf.ipInclude()->useAll());
setIniValue("ipExcludeAll", conf.ipExclude()->useAll());
setIniValue("appBlockAll", conf.appBlockAll()); setIniValue("appBlockAll", conf.appBlockAll());
setIniValue("appAllowAll", conf.appAllowAll()); setIniValue("appAllowAll", conf.appAllowAll());
setIniValue("appGroupBits", conf.appGroupBits(), DEFAULT_APP_GROUP_BITS); setIniValue("appGroupBits", conf.appGroupBits(), DEFAULT_APP_GROUP_BITS);
@ -267,6 +269,53 @@ bool FortSettings::writeConfIni(const FirewallConf &conf)
return iniSync(); 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 bool FortSettings::iniBool(const QString &key, bool defaultValue) const
{ {
return iniValue(key, defaultValue).toBool(); return iniValue(key, defaultValue).toBool();

View File

@ -39,6 +39,9 @@ public:
QString language() const { return iniText("base/language", "en"); } QString language() const { return iniText("base/language", "en"); }
void setLanguage(const QString &v) { setIniValue("base/language", v); } 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(); } QRect windowGeometry() const { return iniValue("window/geometry").toRect(); }
void setWindowGeometry(const QRect &v) { setIniValue("window/geometry", v); } void setWindowGeometry(const QRect &v) { setIniValue("window/geometry", v); }
@ -87,6 +90,9 @@ private:
bool tryToReadConf(FirewallConf &conf, const QString &filePath); bool tryToReadConf(FirewallConf &conf, const QString &filePath);
bool tryToWriteConf(const 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; bool iniBool(const QString &key, bool defaultValue = false) const;
int iniInt(const QString &key, int defaultValue = 0) const; int iniInt(const QString &key, int defaultValue = 0) const;
uint iniUInt(const QString &key, int defaultValue = 0) const; uint iniUInt(const QString &key, int defaultValue = 0) const;

Binary file not shown.

View File

@ -4,32 +4,37 @@
<context> <context>
<name>ConfUtil</name> <name>ConfUtil</name>
<message> <message>
<location filename="../util/confutil.cpp" line="39"/> <location filename="../util/conf/confutil.cpp" line="118"/>
<source>Bad Include IP address: %1</source> <source>Bad Include IP address: %1</source>
<translation>Некорректный IP адрес для включения: %1</translation> <translation>Некорректный IP адрес для включения: %1</translation>
</message> </message>
<message> <message>
<location filename="../util/confutil.cpp" line="46"/> <location filename="../util/conf/confutil.cpp" line="126"/>
<source>Bad Exclude IP address: %1</source> <source>Bad Exclude IP address: %1</source>
<translation>Некорректный IP адрес для исключения: %1</translation> <translation>Некорректный IP адрес для исключения: %1</translation>
</message> </message>
<message> <message>
<location filename="../util/confutil.cpp" line="65"/> <location filename="../util/conf/confutil.cpp" line="137"/>
<source>Size of configuration is too big</source> <source>Too many IP addresses</source>
<translation>Конфигурация слишком большая</translation> <translation>Слишком много IP адресов</translation>
</message> </message>
<message> <message>
<location filename="../util/confutil.cpp" line="118"/> <location filename="../util/conf/confutil.cpp" line="57"/>
<source>Too many application paths</source>
<translation>Слишком много путей приложений</translation>
</message>
<message>
<location filename="../util/conf/confutil.cpp" line="159"/>
<source>Number of Application Groups must be &lt; %1</source> <source>Number of Application Groups must be &lt; %1</source>
<translation>Количество групп приложений должно быть &lt; %1</translation> <translation>Количество групп приложений должно быть &lt; %1</translation>
</message> </message>
<message> <message>
<location filename="../util/confutil.cpp" line="130"/> <location filename="../util/conf/confutil.cpp" line="171"/>
<source>Length of Application Group&apos;s Name must be &lt; %1</source> <source>Length of Application Group&apos;s Name must be &lt; %1</source>
<translation>Длина наименования группы приложения должна быть &lt; %1</translation> <translation>Длина наименования группы приложения должна быть &lt; %1</translation>
</message> </message>
<message> <message>
<location filename="../util/confutil.cpp" line="176"/> <location filename="../util/conf/confutil.cpp" line="217"/>
<source>Length of Application&apos;s Path must be &lt; %1</source> <source>Length of Application&apos;s Path must be &lt; %1</source>
<translation>Длина пути приложения должна быть &lt; %1</translation> <translation>Длина пути приложения должна быть &lt; %1</translation>
</message> </message>
@ -103,33 +108,33 @@
<context> <context>
<name>Ip4Range</name> <name>Ip4Range</name>
<message> <message>
<location filename="../util/net/ip4range.cpp" line="32"/> <location filename="../util/net/ip4range.cpp" line="41"/>
<source>Error at line %1: %2</source> <source>Error at line %1: %2</source>
<translation>Ошибка в строке %1: %2</translation> <translation>Ошибка в строке %1: %2</translation>
</message> </message>
<message> <message>
<location filename="../util/net/ip4range.cpp" line="92"/> <location filename="../util/net/ip4range.cpp" line="100"/>
<source>Bad format</source> <source>Bad format</source>
<translation>Некорректный формат</translation> <translation>Некорректный формат</translation>
</message> </message>
<message> <message>
<location filename="../util/net/ip4range.cpp" line="110"/> <location filename="../util/net/ip4range.cpp" line="118"/>
<source>Bad IP address</source> <source>Bad IP address</source>
<translation>Некорректный IP адрес</translation> <translation>Некорректный IP адрес</translation>
</message> </message>
<message> <message>
<location filename="../util/net/ip4range.cpp" line="117"/> <location filename="../util/net/ip4range.cpp" line="125"/>
<source>Bad second IP address</source> <source>Bad second IP address</source>
<translation>Некорректный второй IP адрес</translation> <translation>Некорректный второй IP адрес</translation>
</message> </message>
<message> <message>
<location filename="../util/net/ip4range.cpp" line="121"/> <location filename="../util/net/ip4range.cpp" line="129"/>
<source>Bad range</source> <source>Bad range</source>
<translation>Некорректный диапазон</translation> <translation>Некорректный диапазон</translation>
</message> </message>
<message> <message>
<location filename="../util/net/ip4range.cpp" line="102"/> <location filename="../util/net/ip4range.cpp" line="110"/>
<location filename="../util/net/ip4range.cpp" line="129"/> <location filename="../util/net/ip4range.cpp" line="137"/>
<source>Bad mask</source> <source>Bad mask</source>
<translation>Некорректная маска</translation> <translation>Некорректная маска</translation>
</message> </message>

View File

@ -6,6 +6,8 @@ import com.fortfirewall 1.0
BasePage { BasePage {
property AddressGroup addressGroup: firewallConf.inetAddressGroup
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
spacing: 10 spacing: 10
@ -13,8 +15,6 @@ BasePage {
AddressesColumn { AddressesColumn {
id: includeAddresses id: includeAddresses
addressGroup: firewallConf.ipInclude
title { title {
text: translationManager.dummyBool text: translationManager.dummyBool
&& qsTranslate("qml", "Include") && qsTranslate("qml", "Include")
@ -25,13 +25,21 @@ BasePage {
text: translationManager.dummyBool text: translationManager.dummyBool
&& qsTranslate("qml", "Include All") && qsTranslate("qml", "Include All")
} }
useAll: addressGroup.includeAll
ipText: addressGroup.includeText
onUseAllToggled: {
addressGroup.includeAll = checked;
}
onIpTextEdited: {
addressGroup.includeText = ipText;
}
} }
AddressesColumn { AddressesColumn {
id: excludeAddresses id: excludeAddresses
addressGroup: firewallConf.ipExclude
title { title {
text: translationManager.dummyBool text: translationManager.dummyBool
&& qsTranslate("qml", "Exclude") && qsTranslate("qml", "Exclude")
@ -42,6 +50,16 @@ BasePage {
text: translationManager.dummyBool text: translationManager.dummyBool
&& qsTranslate("qml", "Exclude All") && qsTranslate("qml", "Exclude All")
} }
useAll: addressGroup.excludeAll
ipText: addressGroup.excludeText
onUseAllToggled: {
addressGroup.excludeAll = checked;
}
onIpTextEdited: {
addressGroup.excludeText = ipText;
}
} }
} }
} }

View File

@ -9,10 +9,14 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
signal useAllToggled(bool checked)
signal ipTextEdited(string ipText)
readonly property alias title: title readonly property alias title: title
readonly property alias checkBoxAll: checkBoxAll readonly property alias checkBoxAll: checkBoxAll
property AddressGroup addressGroup property bool useAll
property string ipText
RowLayout { RowLayout {
Label { Label {
@ -22,9 +26,9 @@ ColumnLayout {
} }
CheckBox { CheckBox {
id: checkBoxAll id: checkBoxAll
checked: addressGroup.useAll checked: useAll
onToggled: { onToggled: {
addressGroup.useAll = checked; useAllToggled(checked);
setConfFlagsEdited(); setConfFlagsEdited();
} }
@ -37,14 +41,14 @@ ColumnLayout {
textArea { textArea {
placeholderText: netUtil.localIpv4Networks().join('\n') placeholderText: netUtil.localIpv4Networks().join('\n')
text: addressGroup.text text: ipText
} }
onTextChanged: { onTextChanged: {
if (addressGroup.text == textArea.text) if (ipText === textArea.text)
return; return;
addressGroup.text = textArea.text; ipTextEdited(textArea.text);
setConfEdited(); setConfEdited();
} }

View File

@ -36,12 +36,12 @@ bool TaskTasix::processResult(FortManager *fortManager)
{ {
#ifndef TASK_TEST #ifndef TASK_TEST
FirewallConf *conf = fortManager->firewallConf(); FirewallConf *conf = fortManager->firewallConf();
AddressGroup *ipExclude = conf->ipExclude(); AddressGroup *inetGroup = conf->inetAddressGroup();
if (ipExclude->text() == m_rangeText) if (inetGroup->excludeText() == m_rangeText)
return false; return false;
ipExclude->setText(m_rangeText); inetGroup->setExcludeText(m_rangeText);
return fortManager->saveOriginConf(successMessage()); return fortManager->saveOriginConf(successMessage());
#else #else

View File

@ -0,0 +1,7 @@
#include "addressrange.h"
AddressRange::AddressRange() :
m_includeAll(false),
m_excludeAll(false)
{
}

View File

@ -0,0 +1,34 @@
#ifndef ADDRESSRANGE_H
#define ADDRESSRANGE_H
#include <QObject>
#include <QVariant>
#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

View File

@ -5,15 +5,16 @@
#define UCHAR quint8 #define UCHAR quint8
#define UINT16 quint16 #define UINT16 quint16
#define UINT32 quint32 #define UINT32 quint32
#define UINT64 quint64
#include "../common/fortconf.h" #include "../../common/fortconf.h"
#include "../common/version.h" #include "../../common/version.h"
#include "../conf/addressgroup.h" #include "../../conf/addressgroup.h"
#include "../conf/appgroup.h" #include "../../conf/appgroup.h"
#include "../conf/firewallconf.h" #include "../../conf/firewallconf.h"
#include "../fortcommon.h" #include "../../fortcommon.h"
#include "fileutil.h" #include "../fileutil.h"
#include "net/ip4range.h" #include "../net/ip4range.h"
#define APP_GROUP_MAX FORT_CONF_GROUP_MAX #define APP_GROUP_MAX FORT_CONF_GROUP_MAX
#define APP_GROUP_NAME_MAX 128 #define APP_GROUP_NAME_MAX 128
@ -34,23 +35,17 @@ void ConfUtil::setErrorMessage(const QString &errorMessage)
int ConfUtil::write(const FirewallConf &conf, QByteArray &buf) int ConfUtil::write(const FirewallConf &conf, QByteArray &buf)
{ {
Ip4Range incRange; quint32 addressGroupsSize = 0;
if (!incRange.fromText(conf.ipInclude()->text())) { numbers_arr_t addressGroupOffsets;
setErrorMessage(tr("Bad Include IP address: %1") addrranges_arr_t addressRanges(conf.addressGroupsList().size());
.arg(incRange.errorLineAndMessage()));
return false;
}
Ip4Range excRange; if (!parseAddressGroups(conf.addressGroupsList(), addressRanges,
if (!excRange.fromText(conf.ipExclude()->text())) { addressGroupOffsets, addressGroupsSize))
setErrorMessage(tr("Bad Exclude IP address: %1")
.arg(excRange.errorLineAndMessage()));
return false; return false;
}
int appPathsLen = 0; quint32 appPathsLen = 0;
QStringList appPaths; QStringList appPaths;
appperms_arr_t appPerms; numbers_arr_t appPerms;
appgroups_map_t appGroupIndexes; appgroups_map_t appGroupIndexes;
if (!parseAppGroups(conf.appGroupsList(), if (!parseAppGroups(conf.appGroupsList(),
@ -58,17 +53,14 @@ int ConfUtil::write(const FirewallConf &conf, QByteArray &buf)
appPerms, appGroupIndexes)) appPerms, appGroupIndexes))
return false; return false;
// Calculate maximum required buffer size if (appPathsLen > FORT_CONF_APPS_LEN_MAX) {
if (incRange.size() > FORT_CONF_IP_MAX setErrorMessage(tr("Too many application paths"));
|| excRange.size() > FORT_CONF_IP_MAX
|| appPathsLen > FORT_CONF_APPS_LEN_MAX) {
setErrorMessage(tr("Size of configuration is too big"));
return false; return false;
} }
// Fill the buffer // Fill the buffer
const int confIoSize = FORT_CONF_IO_CONF_OFF + FORT_CONF_DATA_OFF 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()) + FORT_CONF_STR_DATA_SIZE(appGroupIndexes.size())
+ appPaths.size() * sizeof(quint32) + appPaths.size() * sizeof(quint32)
+ FORT_CONF_STR_HEADER_SIZE(appPaths.size()) + FORT_CONF_STR_HEADER_SIZE(appPaths.size())
@ -77,8 +69,8 @@ int ConfUtil::write(const FirewallConf &conf, QByteArray &buf)
buf.reserve(confIoSize); buf.reserve(confIoSize);
writeData(buf.data(), conf, writeData(buf.data(), conf,
incRange, excRange, appPaths, addressRanges, addressGroupOffsets,
appPerms, appGroupIndexes); appPaths, appPerms, appGroupIndexes);
return confIoSize; return confIoSize;
} }
@ -96,8 +88,6 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf)
confFlags->filter_enabled = conf.filterEnabled(); confFlags->filter_enabled = conf.filterEnabled();
confFlags->stop_traffic = conf.stopTraffic(); confFlags->stop_traffic = conf.stopTraffic();
confFlags->stop_inet_traffic = conf.stopInetTraffic(); 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_block_all = conf.appBlockAll();
confFlags->app_allow_all = conf.appAllowAll(); confFlags->app_allow_all = conf.appAllowAll();
confFlags->log_blocked = conf.logBlocked(); confFlags->log_blocked = conf.logBlocked();
@ -107,10 +97,61 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf)
return flagsSize; return flagsSize;
} }
bool ConfUtil::parseAddressGroups(const QList<AddressGroup *> &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<AppGroup *> &appGroups, bool ConfUtil::parseAppGroups(const QList<AppGroup *> &appGroups,
QStringList &appPaths, QStringList &appPaths,
int &appPathsLen, quint32 &appPathsLen,
appperms_arr_t &appPerms, numbers_arr_t &appPerms,
appgroups_map_t &appGroupIndexes) appgroups_map_t &appGroupIndexes)
{ {
const int groupsCount = appGroups.size(); const int groupsCount = appGroups.size();
@ -213,33 +254,23 @@ QString ConfUtil::parseAppPath(const QStringRef &line)
} }
void ConfUtil::writeData(char *output, const FirewallConf &conf, 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 QStringList &appPaths,
const appperms_arr_t &appPerms, const numbers_arr_t &appPerms,
const appgroups_map_t &appGroupIndexes) const appgroups_map_t &appGroupIndexes)
{ {
PFORT_CONF_IO drvConfIo = (PFORT_CONF_IO) output; PFORT_CONF_IO drvConfIo = (PFORT_CONF_IO) output;
PFORT_CONF drvConf = &drvConfIo->conf; PFORT_CONF drvConf = &drvConfIo->conf;
char *data = (char *) &drvConf->data; char *data = drvConf->data;
const quint32 incRangeSize = incRange.size();
const quint32 excRangeSize = excRange.size();
const quint32 appPathsSize = appPaths.size(); const quint32 appPathsSize = appPaths.size();
quint32 incRangeFromOff, incRangeToOff; quint32 addrGroupsOff;
quint32 excRangeFromOff, excRangeToOff;
quint32 appPathsOff, appPermsOff, appGroupsOff; quint32 appPathsOff, appPermsOff, appGroupsOff;
#define CONF_DATA_OFFSET (data - (char *) &drvConf->data) #define CONF_DATA_OFFSET (data - drvConf->data)
incRangeFromOff = CONF_DATA_OFFSET; addrGroupsOff = CONF_DATA_OFFSET;
writeNumbers(&data, incRange.fromArray()); writeNumbers(&data, addressGroupOffsets);
writeAddressRanges(&data, addressRanges);
incRangeToOff = CONF_DATA_OFFSET;
writeNumbers(&data, incRange.toArray());
excRangeFromOff = CONF_DATA_OFFSET;
writeNumbers(&data, excRange.fromArray());
excRangeToOff = CONF_DATA_OFFSET;
writeNumbers(&data, excRange.toArray());
appGroupsOff = CONF_DATA_OFFSET; appGroupsOff = CONF_DATA_OFFSET;
writeChars(&data, appGroupIndexes.values().toVector()); 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_traffic = conf.stopTraffic();
drvConf->flags.stop_inet_traffic = conf.stopInetTraffic(); 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_block_all = conf.appBlockAll();
drvConf->flags.app_allow_all = conf.appAllowAll(); drvConf->flags.app_allow_all = conf.appAllowAll();
@ -274,18 +302,9 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf,
FortCommon::confAppPermsMaskInit(drvConf); 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->apps_n = appPathsSize;
drvConf->ip_from_include_off = incRangeFromOff; drvConf->addr_groups_off = addrGroupsOff;
drvConf->ip_to_include_off = incRangeToOff;
drvConf->ip_from_exclude_off = excRangeFromOff;
drvConf->ip_to_exclude_off = excRangeToOff;
drvConf->app_groups_off = appGroupsOff; drvConf->app_groups_off = appGroupsOff;
drvConf->app_perms_off = appPermsOff; drvConf->app_perms_off = appPermsOff;
@ -316,6 +335,38 @@ quint16 ConfUtil::writeLimits(struct fort_conf_limit *limits,
return limitBits; 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<quint32> &array) void ConfUtil::writeNumbers(char **data, const QVector<quint32> &array)
{ {
const int arraySize = array.size() * sizeof(quint32); const int arraySize = array.size() * sizeof(quint32);

View File

@ -7,14 +7,19 @@
#include <QObject> #include <QObject>
#include <QVector> #include <QVector>
#include "addressrange.h"
QT_FORWARD_DECLARE_CLASS(AddressGroup)
QT_FORWARD_DECLARE_CLASS(AppGroup) QT_FORWARD_DECLARE_CLASS(AppGroup)
QT_FORWARD_DECLARE_CLASS(FirewallConf) QT_FORWARD_DECLARE_CLASS(FirewallConf)
QT_FORWARD_DECLARE_CLASS(Ip4Range)
QT_FORWARD_DECLARE_STRUCT(fort_conf_limit) QT_FORWARD_DECLARE_STRUCT(fort_conf_limit)
typedef QVector<quint32> numbers_arr_t;
typedef QVarLengthArray<AddressRange, 2> addrranges_arr_t;
typedef QMap<QString, quint32> appperms_map_t; typedef QMap<QString, quint32> appperms_map_t;
typedef QVector<quint32> appperms_arr_t;
typedef QMap<QString, qint8> appgroups_map_t; typedef QMap<QString, qint8> appgroups_map_t;
class ConfUtil : public QObject class ConfUtil : public QObject
@ -37,11 +42,16 @@ public slots:
private: private:
void setErrorMessage(const QString &errorMessage); void setErrorMessage(const QString &errorMessage);
bool parseAddressGroups(const QList<AddressGroup *> &addressGroups,
addrranges_arr_t &addressRanges,
numbers_arr_t &addressGroupOffsets,
quint32 &addressGroupsSize);
// Convert app. groups to plain lists // Convert app. groups to plain lists
bool parseAppGroups(const QList<AppGroup *> &appGroups, bool parseAppGroups(const QList<AppGroup *> &appGroups,
QStringList &appPaths, QStringList &appPaths,
int &appPathsLen, quint32 &appPathsLen,
appperms_arr_t &appPerms, numbers_arr_t &appPerms,
appgroups_map_t &appGroupIndexes); appgroups_map_t &appGroupIndexes);
bool parseApps(const QString &text, bool blocked, bool parseApps(const QString &text, bool blocked,
@ -52,14 +62,20 @@ private:
static QString parseAppPath(const QStringRef &line); static QString parseAppPath(const QStringRef &line);
static void writeData(char *output, const FirewallConf &conf, 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 QStringList &appPaths,
const appperms_arr_t &appPerms, const numbers_arr_t &appPerms,
const appgroups_map_t &appGroupIndexes); const appgroups_map_t &appGroupIndexes);
static quint16 writeLimits(struct fort_conf_limit *limits, static quint16 writeLimits(struct fort_conf_limit *limits,
const QList<AppGroup *> &appGroups); const QList<AppGroup *> &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<quint32> &array); static void writeNumbers(char **data, const QVector<quint32> &array);
static void writeChars(char **data, const QVector<qint8> &array); static void writeChars(char **data, const QVector<qint8> &array);
static void writeStrings(char **data, const QStringList &list); static void writeStrings(char **data, const QStringList &list);

View File

@ -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) void Ip4Range::setErrorLineNo(int lineNo)
{ {
if (m_errorLineNo != lineNo) { if (m_errorLineNo != lineNo) {
@ -52,8 +61,7 @@ QString Ip4Range::toText()
bool Ip4Range::fromText(const QString &text) bool Ip4Range::fromText(const QString &text)
{ {
m_fromArray.clear(); clear();
m_toArray.clear();
ip4range_map_t ipRangeMap; ip4range_map_t ipRangeMap;

View File

@ -40,6 +40,8 @@ signals:
void errorMessageChanged(); void errorMessageChanged();
public slots: public slots:
void clear();
QString toText(); QString toText();
// Parse IPv4 ranges from text // Parse IPv4 ranges from text