diff --git a/src/driver/common/fortconf.h b/src/driver/common/fortconf.h index e2c36001..3c7a4bdd 100644 --- a/src/driver/common/fortconf.h +++ b/src/driver/common/fortconf.h @@ -125,6 +125,7 @@ typedef struct fort_app_flags { UCHAR group_index; UCHAR use_group_perm : 1; + UCHAR apply_child : 1; UCHAR blocked : 1; UCHAR alerted : 1; UCHAR is_new : 1; @@ -148,6 +149,7 @@ typedef struct fort_app_entry typedef struct fort_conf_group { + UINT16 apply_child; UINT16 log_conn; UINT16 fragment_bits; diff --git a/src/ui/conf/appgroup.cpp b/src/ui/conf/appgroup.cpp index 8616abfa..3eb3e734 100644 --- a/src/ui/conf/appgroup.cpp +++ b/src/ui/conf/appgroup.cpp @@ -7,6 +7,7 @@ AppGroup::AppGroup(QObject *parent) : QObject(parent), m_edited(false), m_enabled(true), + m_applyChild(false), m_logConn(true), m_fragmentPacket(false), m_periodEnabled(false), @@ -23,6 +24,14 @@ void AppGroup::setEnabled(bool enabled) } } +void AppGroup::setApplyChild(bool on) +{ + if (bool(m_applyChild) != on) { + m_applyChild = on; + setEdited(true); + } +} + void AppGroup::setLogConn(bool on) { if (bool(m_logConn) != on) { @@ -149,6 +158,7 @@ void AppGroup::copy(const AppGroup &o) m_edited = o.edited(); m_enabled = o.enabled(); + m_applyChild = o.applyChild(); m_logConn = o.logConn(); m_fragmentPacket = o.fragmentPacket(); @@ -175,6 +185,7 @@ QVariant AppGroup::toVariant() const map["edited"] = edited(); map["enabled"] = enabled(); + map["applyChild"] = applyChild(); map["logConn"] = logConn(); map["fragmentPacket"] = fragmentPacket(); @@ -203,6 +214,7 @@ void AppGroup::fromVariant(const QVariant &v) m_edited = map["edited"].toBool(); m_enabled = map["enabled"].toBool(); + m_applyChild = map["applyChild"].toBool(); m_logConn = map["logConn"].toBool(); m_fragmentPacket = map["fragmentPacket"].toBool(); diff --git a/src/ui/conf/appgroup.h b/src/ui/conf/appgroup.h index 8fc6c240..10aa1672 100644 --- a/src/ui/conf/appgroup.h +++ b/src/ui/conf/appgroup.h @@ -19,6 +19,9 @@ public: bool enabled() const { return m_enabled; } void setEnabled(bool enabled); + bool applyChild() const { return m_applyChild; } + void setApplyChild(bool on); + bool logConn() const { return m_logConn; } void setLogConn(bool on); @@ -74,6 +77,7 @@ private: bool m_edited : 1; bool m_enabled : 1; + bool m_applyChild : 1; bool m_logConn : 1; bool m_fragmentPacket : 1; diff --git a/src/ui/conf/confmanager.cpp b/src/ui/conf/confmanager.cpp index 016e1aff..6a869953 100644 --- a/src/ui/conf/confmanager.cpp +++ b/src/ui/conf/confmanager.cpp @@ -34,7 +34,7 @@ Q_LOGGING_CATEGORY(CLOG_CONF_MANAGER, "conf") #define logWarning() qCWarning(CLOG_CONF_MANAGER, ) #define logCritical() qCCritical(CLOG_CONF_MANAGER, ) -#define DATABASE_USER_VERSION 10 +#define DATABASE_USER_VERSION 11 namespace { @@ -44,7 +44,7 @@ const char *const sqlSelectAddressGroups = "SELECT addr_group_id, include_all, e " FROM address_group" " ORDER BY order_index;"; -const char *const sqlSelectAppGroups = "SELECT app_group_id, enabled, log_conn," +const char *const sqlSelectAppGroups = "SELECT app_group_id, enabled, apply_child, log_conn," " fragment_packet, period_enabled," " limit_in_enabled, limit_out_enabled," " speed_limit_in, speed_limit_out," @@ -67,21 +67,22 @@ const char *const sqlUpdateAddressGroup = "UPDATE address_group" " WHERE addr_group_id = ?1;"; const char *const sqlInsertAppGroup = - "INSERT INTO app_group(app_group_id, order_index, enabled, log_conn," + "INSERT INTO app_group(app_group_id, order_index, enabled," + " apply_child, log_conn," " fragment_packet, period_enabled," " limit_in_enabled, limit_out_enabled," " speed_limit_in, speed_limit_out," " name, block_text, allow_text," " period_from, period_to)" - " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15);"; + " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16);"; const char *const sqlUpdateAppGroup = "UPDATE app_group" - " SET order_index = ?2, enabled = ?3, log_conn = ?4," - " fragment_packet = ?5, period_enabled = ?6," - " limit_in_enabled = ?7, limit_out_enabled = ?8," - " speed_limit_in = ?9, speed_limit_out = ?10," - " name = ?11, block_text = ?12, allow_text = ?13," - " period_from = ?14, period_to = ?15" + " SET order_index = ?2, enabled = ?3, apply_child = ?4," + " log_conn = ?5, fragment_packet = ?6," + " period_enabled = ?7, limit_in_enabled = ?8," + " limit_out_enabled = ?9, speed_limit_in = ?10," + " speed_limit_out = ?11, name = ?12, block_text = ?13," + " allow_text = ?14, period_from = ?15, period_to = ?16" " WHERE app_group_id = ?1;"; const char *const sqlDeleteAppGroup = "DELETE FROM app_group" @@ -107,6 +108,7 @@ const char *const sqlSelectAppById = "SELECT" " g.order_index as group_index," " t.path," " t.use_group_perm," + " t.apply_child," " t.blocked" " FROM app t" " JOIN app_group g ON g.app_group_id = t.app_group_id" @@ -116,6 +118,7 @@ const char *const sqlSelectApps = "SELECT" " g.order_index as group_index," " t.path," " t.use_group_perm," + " t.apply_child," " t.blocked," " (alert.app_id IS NOT NULL) as alerted" " FROM app t" @@ -127,21 +130,22 @@ const char *const sqlSelectEndAppsCount = "SELECT COUNT(*) FROM app" " AND blocked = 0;"; const char *const sqlSelectEndedApps = "SELECT t.app_id, g.order_index as group_index," - " t.path, t.name, t.use_group_perm" + " t.path, t.name, t.use_group_perm, t.apply_child" " FROM app t" " JOIN app_group g ON g.app_group_id = t.app_group_id" " WHERE end_time <= ?1 AND blocked = 0;"; const char *const sqlSelectAppIdByPath = "SELECT app_id FROM app WHERE path = ?1;"; -const char *const sqlUpsertApp = - "INSERT INTO app(app_group_id, path, name, use_group_perm, blocked," - " creat_time, end_time)" - " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7)" - " ON CONFLICT(path) DO UPDATE" - " SET app_group_id = ?1, name = ?3, use_group_perm = ?4, blocked = ?5," - " creat_time = ?6, end_time = ?7" - " RETURNING app_id;"; +const char *const sqlUpsertApp = "INSERT INTO app(app_group_id, path, name," + " use_group_perm, apply_child, blocked," + " creat_time, end_time)" + " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)" + " ON CONFLICT(path) DO UPDATE" + " SET app_group_id = ?1, name = ?3," + " use_group_perm = ?4, apply_child = ?5, blocked = ?6," + " creat_time = ?7, end_time = ?8" + " RETURNING app_id;"; const char *const sqlInsertAppAlert = "INSERT INTO app_alert(app_id) VALUES(?1);"; @@ -151,7 +155,7 @@ const char *const sqlDeleteAppAlert = "DELETE FROM app_alert WHERE app_id = ?1;" const char *const sqlUpdateApp = "UPDATE app" " SET app_group_id = ?2, name = ?3, use_group_perm = ?4," - " blocked = ?5, end_time = ?6" + " apply_child = ?5, blocked = ?6, end_time = ?7" " WHERE app_id = ?1;"; const char *const sqlUpdateAppName = "UPDATE app SET name = ?2 WHERE app_id = ?1;"; @@ -283,18 +287,19 @@ bool loadAppGroups(SqliteDb *db, FirewallConf &conf) appGroup->setId(stmt.columnInt64(0)); appGroup->setEnabled(stmt.columnBool(1)); - appGroup->setLogConn(stmt.columnBool(2)); - appGroup->setFragmentPacket(stmt.columnBool(3)); - appGroup->setPeriodEnabled(stmt.columnBool(4)); - appGroup->setLimitInEnabled(stmt.columnBool(5)); - appGroup->setLimitOutEnabled(stmt.columnBool(6)); - appGroup->setSpeedLimitIn(quint32(stmt.columnInt(7))); - appGroup->setSpeedLimitOut(quint32(stmt.columnInt(8))); - appGroup->setName(stmt.columnText(9)); - appGroup->setBlockText(stmt.columnText(10)); - appGroup->setAllowText(stmt.columnText(11)); - appGroup->setPeriodFrom(stmt.columnText(12)); - appGroup->setPeriodTo(stmt.columnText(13)); + appGroup->setApplyChild(stmt.columnBool(2)); + appGroup->setLogConn(stmt.columnBool(3)); + appGroup->setFragmentPacket(stmt.columnBool(4)); + appGroup->setPeriodEnabled(stmt.columnBool(5)); + appGroup->setLimitInEnabled(stmt.columnBool(6)); + appGroup->setLimitOutEnabled(stmt.columnBool(7)); + appGroup->setSpeedLimitIn(quint32(stmt.columnInt(8))); + appGroup->setSpeedLimitOut(quint32(stmt.columnInt(9))); + appGroup->setName(stmt.columnText(10)); + appGroup->setBlockText(stmt.columnText(11)); + appGroup->setAllowText(stmt.columnText(12)); + appGroup->setPeriodFrom(stmt.columnText(13)); + appGroup->setPeriodTo(stmt.columnText(14)); appGroup->setEdited(false); conf.addAppGroup(appGroup); @@ -311,10 +316,11 @@ bool saveAppGroup(SqliteDb *db, AppGroup *appGroup, int orderIndex) const auto vars = QVariantList() << (rowExists ? appGroup->id() : QVariant()) << orderIndex << appGroup->enabled() - << appGroup->logConn() << appGroup->fragmentPacket() << appGroup->periodEnabled() - << appGroup->limitInEnabled() << appGroup->limitOutEnabled() << appGroup->speedLimitIn() - << appGroup->speedLimitOut() << appGroup->name() << appGroup->blockText() - << appGroup->allowText() << appGroup->periodFrom() << appGroup->periodTo(); + << appGroup->applyChild() << appGroup->logConn() << appGroup->fragmentPacket() + << appGroup->periodEnabled() << appGroup->limitInEnabled() + << appGroup->limitOutEnabled() << appGroup->speedLimitIn() << appGroup->speedLimitOut() + << appGroup->name() << appGroup->blockText() << appGroup->allowText() + << appGroup->periodFrom() << appGroup->periodTo(); const char *sql = rowExists ? sqlUpdateAppGroup : sqlInsertAppGroup; @@ -658,8 +664,8 @@ void ConfManager::logBlockedApp(const LogEntryBlocked &logEntry) const QString appName = IoC()->appName(appPath); constexpr int groupIndex = 0; // "Main" app. group - const bool ok = addOrUpdateApp( - appPath, appName, QDateTime(), groupIndex, false, logEntry.blocked(), true); + const bool ok = addOrUpdateApp(appPath, appName, QDateTime(), groupIndex, + /*useGroupPerm=*/false, /*applyChild=*/false, logEntry.blocked(), /*alerted=*/true); if (ok) { emitAppAlerted(); } @@ -671,12 +677,13 @@ qint64 ConfManager::appIdByPath(const QString &appPath) } bool ConfManager::addApp(const QString &appPath, const QString &appName, const QDateTime &endTime, - int groupIndex, bool useGroupPerm, bool blocked) + int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) { - if (!updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, blocked)) + if (!updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, applyChild, applyChild, blocked)) return false; - return addOrUpdateApp(appPath, appName, endTime, groupIndex, useGroupPerm, blocked, false); + return addOrUpdateApp( + appPath, appName, endTime, groupIndex, useGroupPerm, applyChild, blocked, false); } bool ConfManager::deleteApp(qint64 appId) @@ -732,21 +739,22 @@ bool ConfManager::purgeApps() } bool ConfManager::updateApp(qint64 appId, const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked) + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) { const AppGroup *appGroup = conf()->appGroupAt(groupIndex); if (appGroup->isNull()) return false; - if (!updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, blocked)) + if (!updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, applyChild, blocked)) return false; bool ok = false; sqliteDb()->beginTransaction(); - const auto vars = QVariantList() << appId << appGroup->id() << appName << useGroupPerm - << blocked << (!endTime.isNull() ? endTime : QVariant()); + const auto vars = QVariantList() + << appId << appGroup->id() << appName << useGroupPerm << applyChild << blocked + << (!endTime.isNull() ? endTime : QVariant()); sqliteDb()->executeEx(sqlUpdateApp, vars, 0, &ok); if (ok) { @@ -821,10 +829,11 @@ bool ConfManager::walkApps(const std::function &func) const int groupIndex = stmt.columnInt(0); const QString appPath = stmt.columnText(1); const bool useGroupPerm = stmt.columnBool(2); - const bool blocked = stmt.columnBool(3); - const bool alerted = stmt.columnBool(4); + const bool applyChild = stmt.columnBool(3); + const bool blocked = stmt.columnBool(4); + const bool alerted = stmt.columnBool(5); - if (!func(groupIndex, useGroupPerm, blocked, alerted, appPath)) + if (!func(groupIndex, useGroupPerm, applyChild, blocked, alerted, appPath)) return false; } @@ -850,8 +859,10 @@ void ConfManager::updateAppEndTimes() const QString appPath = stmt.columnText(3); const QString appName = stmt.columnText(4); const bool useGroupPerm = stmt.columnBool(5); + const bool applyChild = stmt.columnBool(6); - updateApp(appId, appPath, appName, QDateTime(), groupIndex, useGroupPerm, true); + updateApp(appId, appPath, appName, QDateTime(), groupIndex, useGroupPerm, applyChild, + /*blocked=*/true); } } @@ -1042,7 +1053,8 @@ bool ConfManager::updateDriverConf(bool onlyFlags) } bool ConfManager::addOrUpdateApp(const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked, bool alerted) + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, + bool alerted) { const AppGroup *appGroup = conf()->appGroupAt(groupIndex); if (appGroup->isNull()) @@ -1053,7 +1065,7 @@ bool ConfManager::addOrUpdateApp(const QString &appPath, const QString &appName, sqliteDb()->beginTransaction(); const auto vars = QVariantList() - << appGroup->id() << appPath << appName << useGroupPerm << blocked + << appGroup->id() << appPath << appName << useGroupPerm << applyChild << blocked << QDateTime::currentDateTime() << (!endTime.isNull() ? endTime : QVariant()); const auto appIdVar = sqliteDb()->executeEx(sqlUpsertApp, vars, 1, &ok); @@ -1090,10 +1102,11 @@ bool ConfManager::updateDriverAppBlocked(qint64 appId, bool blocked, bool &chang const int groupIndex = stmt.columnInt(0); const QString appPath = stmt.columnText(1); const bool useGroupPerm = stmt.columnBool(2); - const bool wasBlocked = stmt.columnBool(3); + const bool applyChild = stmt.columnBool(3); + const bool wasBlocked = stmt.columnBool(4); if (blocked != wasBlocked) { - if (!updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, blocked)) + if (!updateDriverUpdateApp(appPath, groupIndex, useGroupPerm, applyChild, blocked)) return false; changed = true; @@ -1104,17 +1117,18 @@ bool ConfManager::updateDriverAppBlocked(qint64 appId, bool blocked, bool &chang bool ConfManager::updateDriverDeleteApp(const QString &appPath) { - return updateDriverUpdateApp(appPath, 0, false, false, true); + return updateDriverUpdateApp(appPath, /*groupIndex=*/0, /*useGroupPerm=*/false, + /*applyChild=*/false, /*blocked=*/false, /*remove=*/true); } -bool ConfManager::updateDriverUpdateApp( - const QString &appPath, int groupIndex, bool useGroupPerm, bool blocked, bool remove) +bool ConfManager::updateDriverUpdateApp(const QString &appPath, int groupIndex, bool useGroupPerm, + bool applyChild, bool blocked, bool remove) { ConfUtil confUtil; QByteArray buf; - const int entrySize = - confUtil.writeAppEntry(groupIndex, useGroupPerm, blocked, false, false, appPath, buf); + const int entrySize = confUtil.writeAppEntry( + groupIndex, useGroupPerm, applyChild, blocked, false, false, appPath, buf); if (entrySize == 0) { showErrorMessage(confUtil.errorMessage()); diff --git a/src/ui/conf/confmanager.h b/src/ui/conf/confmanager.h index 92c39bb0..c7bb7a4f 100644 --- a/src/ui/conf/confmanager.h +++ b/src/ui/conf/confmanager.h @@ -59,11 +59,12 @@ public: qint64 appIdByPath(const QString &appPath); virtual bool addApp(const QString &appPath, const QString &appName, const QDateTime &endTime, - int groupIndex, bool useGroupPerm, bool blocked); + int groupIndex, bool useGroupPerm, bool applyChild, bool blocked); virtual bool deleteApp(qint64 appId); virtual bool purgeApps(); virtual bool updateApp(qint64 appId, const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked); + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, + bool blocked); virtual bool updateAppBlocked(qint64 appId, bool blocked); virtual bool updateAppName(qint64 appId, const QString &appName); @@ -120,12 +121,12 @@ private: void emitAppUpdated(); bool addOrUpdateApp(const QString &appPath, const QString &appName, const QDateTime &endTime, - int groupIndex, bool useGroupPerm, bool blocked, bool alerted); + int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, bool alerted); bool updateDriverAppBlocked(qint64 appId, bool blocked, bool &changed); bool updateDriverDeleteApp(const QString &appPath); bool updateDriverUpdateApp(const QString &appPath, int groupIndex, bool useGroupPerm, - bool blocked, bool remove = false); + bool applyChild, bool blocked, bool remove = false); bool updateDriverZoneFlag(int zoneId, bool enabled); bool loadFromDb(FirewallConf &conf, bool &isNew); diff --git a/src/ui/conf/migrations/1.sql b/src/ui/conf/migrations/1.sql index ca7b0865..a9805966 100644 --- a/src/ui/conf/migrations/1.sql +++ b/src/ui/conf/migrations/1.sql @@ -84,6 +84,7 @@ CREATE TABLE app_group( app_group_id INTEGER PRIMARY KEY, order_index INTEGER NOT NULL, enabled BOOLEAN NOT NULL, + apply_child BOOLEAN NOT NULL DEFAULT 0, log_conn BOOLEAN NOT NULL DEFAULT 1, fragment_packet BOOLEAN NOT NULL, period_enabled BOOLEAN NOT NULL, @@ -105,6 +106,7 @@ CREATE TABLE app( path TEXT NOT NULL, name TEXT, use_group_perm BOOLEAN NOT NULL DEFAULT 1, + apply_child BOOLEAN NOT NULL DEFAULT 0, blocked BOOLEAN NOT NULL, creat_time INTEGER NOT NULL, end_time INTEGER, diff --git a/src/ui/form/opt/pages/applicationspage.cpp b/src/ui/form/opt/pages/applicationspage.cpp index 6536c5f3..53a02a47 100644 --- a/src/ui/form/opt/pages/applicationspage.cpp +++ b/src/ui/form/opt/pages/applicationspage.cpp @@ -79,6 +79,8 @@ void ApplicationsPage::onRetranslateUi() m_cbAllowAll->setText(tr("Allow All")); m_btGroupOptions->setText(tr("Options")); + m_cbApplyChild->setText(tr("Apply same rules to child processes")); + m_cscLimitIn->checkBox()->setText(tr("Download speed limit:")); m_cscLimitOut->checkBox()->setText(tr("Upload speed limit:")); retranslateGroupLimits(); @@ -373,14 +375,16 @@ void ApplicationsPage::setupGroupPeriodEnabled() void ApplicationsPage::setupGroupOptions() { + setupGroupApplyChild(); setupGroupLimitIn(); setupGroupLimitOut(); setupGroupLogConn(); setupGroupFragmentPacket(); // Menu - const QList menuWidgets = { m_cscLimitIn, m_cscLimitOut, - ControlUtil::createSeparator(), m_cbLogConn, m_cbFragmentPacket }; + const QList menuWidgets = { m_cbApplyChild, ControlUtil::createSeparator(), + m_cscLimitIn, m_cscLimitOut, ControlUtil::createSeparator(), m_cbLogConn, + m_cbFragmentPacket }; auto layout = ControlUtil::createLayoutByWidgets(menuWidgets); auto menu = ControlUtil::createMenuByLayout(layout, this); @@ -389,6 +393,18 @@ void ApplicationsPage::setupGroupOptions() m_btGroupOptions->setMenu(menu); } +void ApplicationsPage::setupGroupApplyChild() +{ + m_cbApplyChild = ControlUtil::createCheckBox(false, [&](bool checked) { + if (appGroup()->applyChild() == checked) + return; + + appGroup()->setApplyChild(checked); + + ctrl()->setOptEdited(); + }); +} + void ApplicationsPage::setupGroupLimitIn() { m_cscLimitIn = createGroupLimit(); @@ -549,6 +565,8 @@ void ApplicationsPage::setupSplitterButtons() void ApplicationsPage::updateGroup() { + m_cbApplyChild->setChecked(appGroup()->applyChild()); + m_cscLimitIn->checkBox()->setChecked(appGroup()->limitInEnabled()); m_cscLimitIn->spinBox()->setValue(int(appGroup()->speedLimitIn())); diff --git a/src/ui/form/opt/pages/applicationspage.h b/src/ui/form/opt/pages/applicationspage.h index 9a661e0b..dba4cdfe 100644 --- a/src/ui/form/opt/pages/applicationspage.h +++ b/src/ui/form/opt/pages/applicationspage.h @@ -47,6 +47,7 @@ private: void setupGroupPeriod(); void setupGroupPeriodEnabled(); void setupGroupOptions(); + void setupGroupApplyChild(); void setupGroupLimitIn(); void setupGroupLimitOut(); void setupGroupLogConn(); @@ -80,6 +81,7 @@ private: QCheckBox *m_cbGroupEnabled = nullptr; CheckTimePeriod *m_ctpGroupPeriod = nullptr; QPushButton *m_btGroupOptions = nullptr; + QCheckBox *m_cbApplyChild = nullptr; CheckSpinCombo *m_cscLimitIn = nullptr; CheckSpinCombo *m_cscLimitOut = nullptr; QCheckBox *m_cbLogConn = nullptr; diff --git a/src/ui/form/prog/programeditdialog.cpp b/src/ui/form/prog/programeditdialog.cpp index 4f6d164a..f9b02a31 100644 --- a/src/ui/form/prog/programeditdialog.cpp +++ b/src/ui/form/prog/programeditdialog.cpp @@ -76,6 +76,7 @@ void ProgramEditDialog::initialize(const AppRow &appRow, const QVector & m_btGetName->setEnabled(isSingleSelection); m_comboAppGroup->setCurrentIndex(appRow.groupIndex); m_cbUseGroupPerm->setChecked(appRow.useGroupPerm); + m_cbApplyChild->setChecked(appRow.applyChild); m_rbAllowApp->setChecked(!appRow.blocked); m_rbBlockApp->setChecked(appRow.blocked); m_cscBlockAppIn->checkBox()->setChecked(false); @@ -116,6 +117,7 @@ void ProgramEditDialog::retranslateUi() m_labelAppGroup->setText(tr("Application Group:")); m_cbUseGroupPerm->setText(tr("Use Application Group's Enabled State")); + m_cbApplyChild->setText(tr("Apply same rules to child processes")); m_rbAllowApp->setText(tr("Allow")); m_rbBlockApp->setText(tr("Block")); @@ -222,6 +224,11 @@ QLayout *ProgramEditDialog::setupAppLayout() layout->addRow(QString(), m_cbUseGroupPerm); + // Apply Child + m_cbApplyChild = new QCheckBox(); + + layout->addRow(QString(), m_cbApplyChild); + return layout; } @@ -361,6 +368,7 @@ bool ProgramEditDialog::save() const int groupIndex = m_comboAppGroup->currentIndex(); const bool useGroupPerm = m_cbUseGroupPerm->isChecked(); + const bool applyChild = m_cbApplyChild->isChecked(); const bool blocked = m_rbBlockApp->isChecked(); QDateTime endTime; @@ -376,28 +384,29 @@ bool ProgramEditDialog::save() // Add new app or edit non-selected app if (appIdsCount == 0) { - return confManager()->addApp(appPath, appName, endTime, groupIndex, useGroupPerm, blocked); + return confManager()->addApp( + appPath, appName, endTime, groupIndex, useGroupPerm, applyChild, blocked); } // Edit selected app if (isSingleSelection) { - return saveApp(appPath, appName, endTime, groupIndex, useGroupPerm, blocked); + return saveApp(appPath, appName, endTime, groupIndex, useGroupPerm, applyChild, blocked); } // Edit selected apps - return saveMulti(endTime, groupIndex, useGroupPerm, blocked); + return saveMulti(endTime, groupIndex, useGroupPerm, applyChild, blocked); } bool ProgramEditDialog::saveApp(const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked) + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) { const bool appEdited = (appPath != m_appRow.appPath || groupIndex != m_appRow.groupIndex - || useGroupPerm != m_appRow.useGroupPerm || blocked != m_appRow.blocked - || endTime != m_appRow.endTime); + || useGroupPerm != m_appRow.useGroupPerm || applyChild != m_appRow.applyChild + || blocked != m_appRow.blocked || endTime != m_appRow.endTime); if (appEdited) { - return confManager()->updateApp( - m_appRow.appId, appPath, appName, endTime, groupIndex, useGroupPerm, blocked); + return confManager()->updateApp(m_appRow.appId, appPath, appName, endTime, groupIndex, + useGroupPerm, applyChild, blocked); } if (appName == m_appRow.appName) @@ -407,13 +416,13 @@ bool ProgramEditDialog::saveApp(const QString &appPath, const QString &appName, } bool ProgramEditDialog::saveMulti( - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked) + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) { for (qint64 appId : m_appIdList) { const auto appRow = appListModel()->appRowById(appId); if (!confManager()->updateApp(appId, appRow.appPath, appRow.appName, endTime, groupIndex, - useGroupPerm, blocked)) + useGroupPerm, applyChild, blocked)) return false; } diff --git a/src/ui/form/prog/programeditdialog.h b/src/ui/form/prog/programeditdialog.h index 558196c7..7ca07d64 100644 --- a/src/ui/form/prog/programeditdialog.h +++ b/src/ui/form/prog/programeditdialog.h @@ -53,8 +53,9 @@ private: bool save(); bool saveApp(const QString &appPath, const QString &appName, const QDateTime &endTime, - int groupIndex, bool useGroupPerm, bool blocked); - bool saveMulti(const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked); + int groupIndex, bool useGroupPerm, bool applyChild, bool blocked); + bool saveMulti(const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, + bool blocked); private: ProgramsController *m_ctrl = nullptr; @@ -68,6 +69,7 @@ private: QLabel *m_labelAppGroup = nullptr; QComboBox *m_comboAppGroup = nullptr; QCheckBox *m_cbUseGroupPerm = nullptr; + QCheckBox *m_cbApplyChild = nullptr; QRadioButton *m_rbAllowApp = nullptr; QRadioButton *m_rbBlockApp = nullptr; CheckSpinCombo *m_cscBlockAppIn = nullptr; diff --git a/src/ui/model/applistmodel.cpp b/src/ui/model/applistmodel.cpp index 3dd0768d..3ddb86bb 100644 --- a/src/ui/model/applistmodel.cpp +++ b/src/ui/model/applistmodel.cpp @@ -277,10 +277,11 @@ bool AppListModel::updateAppRow(const QString &sql, const QVariantList &vars, Ap appRow.appPath = stmt.columnText(2); appRow.appName = stmt.columnText(3); appRow.useGroupPerm = stmt.columnBool(4); - appRow.blocked = stmt.columnBool(5); - appRow.alerted = stmt.columnBool(6); - appRow.endTime = stmt.columnDateTime(7); - appRow.creatTime = stmt.columnDateTime(8); + appRow.applyChild = stmt.columnBool(5); + appRow.blocked = stmt.columnBool(6); + appRow.alerted = stmt.columnBool(7); + appRow.endTime = stmt.columnDateTime(8); + appRow.creatTime = stmt.columnDateTime(9); return true; } @@ -321,6 +322,7 @@ QString AppListModel::sqlBase() const " t.path," " t.name," " t.use_group_perm," + " t.apply_child," " t.blocked," " (alert.app_id IS NOT NULL) as alerted," " t.end_time," diff --git a/src/ui/model/applistmodel.h b/src/ui/model/applistmodel.h index fc4210ec..cca123c8 100644 --- a/src/ui/model/applistmodel.h +++ b/src/ui/model/applistmodel.h @@ -14,6 +14,7 @@ class SqliteDb; struct AppRow : TableRow { bool useGroupPerm = true; + bool applyChild = false; bool blocked = false; bool alerted = false; diff --git a/src/ui/rpc/confmanagerrpc.cpp b/src/ui/rpc/confmanagerrpc.cpp index 74d0332d..fb967b62 100644 --- a/src/ui/rpc/confmanagerrpc.cpp +++ b/src/ui/rpc/confmanagerrpc.cpp @@ -15,10 +15,10 @@ ConfManagerRpc::ConfManagerRpc(const QString &filePath, QObject *parent) : } bool ConfManagerRpc::addApp(const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked) + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) { return IoC()->doOnServer(Control::Rpc_ConfManager_addApp, - { appPath, appName, endTime, groupIndex, useGroupPerm, blocked }); + { appPath, appName, endTime, groupIndex, useGroupPerm, applyChild, blocked }); } bool ConfManagerRpc::deleteApp(qint64 appId) @@ -32,10 +32,10 @@ bool ConfManagerRpc::purgeApps() } bool ConfManagerRpc::updateApp(qint64 appId, const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked) + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) { return IoC()->doOnServer(Control::Rpc_ConfManager_updateApp, - { appId, appPath, appName, endTime, groupIndex, useGroupPerm, blocked }); + { appId, appPath, appName, endTime, groupIndex, useGroupPerm, applyChild, blocked }); } bool ConfManagerRpc::updateAppBlocked(qint64 appId, bool blocked) diff --git a/src/ui/rpc/confmanagerrpc.h b/src/ui/rpc/confmanagerrpc.h index 68fa7012..55b445a5 100644 --- a/src/ui/rpc/confmanagerrpc.h +++ b/src/ui/rpc/confmanagerrpc.h @@ -14,11 +14,12 @@ public: explicit ConfManagerRpc(const QString &filePath, QObject *parent = nullptr); bool addApp(const QString &appPath, const QString &appName, const QDateTime &endTime, - int groupIndex, bool useGroupPerm, bool blocked) override; + int groupIndex, bool useGroupPerm, bool applyChild, bool blocked) override; bool deleteApp(qint64 appId) override; bool purgeApps() override; bool updateApp(qint64 appId, const QString &appPath, const QString &appName, - const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool blocked) override; + const QDateTime &endTime, int groupIndex, bool useGroupPerm, bool applyChild, + bool blocked) override; bool updateAppBlocked(qint64 appId, bool blocked) override; bool updateAppName(qint64 appId, const QString &appName) override; diff --git a/src/ui/rpc/rpcmanager.cpp b/src/ui/rpc/rpcmanager.cpp index aca811e7..6b00ae1d 100644 --- a/src/ui/rpc/rpcmanager.cpp +++ b/src/ui/rpc/rpcmanager.cpp @@ -51,7 +51,7 @@ inline bool processConfManager_addApp(ConfManager *confManager, const QVariantLi { return confManager->addApp(args.value(0).toString(), args.value(1).toString(), args.value(2).toDateTime(), args.value(3).toInt(), args.value(4).toBool(), - args.value(5).toBool()); + args.value(5).toBool(), args.value(6).toBool()); } inline bool processConfManager_deleteApp(ConfManager *confManager, const QVariantList &args) @@ -63,7 +63,7 @@ inline bool processConfManager_updateApp(ConfManager *confManager, const QVarian { return confManager->updateApp(args.value(0).toLongLong(), args.value(1).toString(), args.value(2).toString(), args.value(3).toDateTime(), args.value(4).toInt(), - args.value(5).toBool(), args.value(6).toBool()); + args.value(5).toBool(), args.value(6).toBool(), args.value(7).toBool()); } inline bool processConfManager_updateAppBlocked(ConfManager *confManager, const QVariantList &args) diff --git a/src/ui/util/conf/confappswalker.h b/src/ui/util/conf/confappswalker.h index cfe1a8b1..b82d3b9b 100644 --- a/src/ui/util/conf/confappswalker.h +++ b/src/ui/util/conf/confappswalker.h @@ -5,8 +5,8 @@ #include -using walkAppsCallback = bool( - int groupIndex, bool useGroupPerm, bool blocked, bool alerted, const QString &appPath); +using walkAppsCallback = bool(int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, + bool alerted, const QString &appPath); class ConfAppsWalker { diff --git a/src/ui/util/conf/confutil.cpp b/src/ui/util/conf/confutil.cpp index 642d15ce..ae3d878a 100644 --- a/src/ui/util/conf/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -124,13 +124,13 @@ int ConfUtil::writeFlags(const FirewallConf &conf, QByteArray &buf) return flagsSize; } -int ConfUtil::writeAppEntry(int groupIndex, bool useGroupPerm, bool blocked, bool alerted, - bool isNew, const QString &appPath, QByteArray &buf) +int ConfUtil::writeAppEntry(int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, + bool alerted, bool isNew, const QString &appPath, QByteArray &buf) { appentry_map_t exeAppsMap; quint32 exeAppsSize = 0; - if (!addApp(groupIndex, useGroupPerm, blocked, alerted, isNew, appPath, exeAppsMap, + if (!addApp(groupIndex, useGroupPerm, applyChild, blocked, alerted, isNew, appPath, exeAppsMap, exeAppsSize)) return 0; @@ -340,11 +340,12 @@ bool ConfUtil::parseExeApps( if (Q_UNLIKELY(!confAppsWalker)) return true; - return confAppsWalker->walkApps([&](int groupIndex, bool useGroupPerm, bool blocked, - bool alerted, const QString &appPath) -> bool { - return addApp( - groupIndex, useGroupPerm, blocked, alerted, true, appPath, exeAppsMap, exeAppsSize); - }); + return confAppsWalker->walkApps( + [&](int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, bool alerted, + const QString &appPath) -> bool { + return addApp(groupIndex, useGroupPerm, applyChild, blocked, alerted, + /*isNew=*/true, appPath, exeAppsMap, exeAppsSize); + }); } bool ConfUtil::parseAppsText(int groupIndex, bool blocked, const QString &text, @@ -380,11 +381,13 @@ bool ConfUtil::addParsedApp(int groupIndex, bool blocked, bool isWild, bool isPr appentry_map_t &appsMap = isWild ? wildAppsMap : (isPrefix ? prefixAppsMap : exeAppsMap); quint32 &appsSize = isWild ? wildAppsSize : (isPrefix ? prefixAppsSize : exeAppsSize); - return addApp(groupIndex, true, blocked, false, true, appPath, appsMap, appsSize, false); + return addApp(groupIndex, /*useGroupPerm=*/true, /*applyChild=*/false, blocked, + /*alerted=*/false, /*isNew=*/true, appPath, appsMap, appsSize, /*canOverwrite=*/false); } -bool ConfUtil::addApp(int groupIndex, bool useGroupPerm, bool blocked, bool alerted, bool isNew, - const QString &appPath, appentry_map_t &appsMap, quint32 &appsSize, bool canOverwrite) +bool ConfUtil::addApp(int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, + bool alerted, bool isNew, const QString &appPath, appentry_map_t &appsMap, + quint32 &appsSize, bool canOverwrite) { const QString kernelPath = FileUtil::pathToKernelPath(appPath); @@ -408,6 +411,7 @@ bool ConfUtil::addApp(int groupIndex, bool useGroupPerm, bool blocked, bool aler appEntry.path_len = appPathLen; appEntry.flags.group_index = quint8(groupIndex); appEntry.flags.use_group_perm = useGroupPerm; + appEntry.flags.apply_child = applyChild; appEntry.flags.blocked = blocked; appEntry.flags.alerted = alerted; appEntry.flags.is_new = isNew; @@ -495,7 +499,8 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf, writeApps(&data, exeAppsMap); #undef CONF_DATA_OFFSET - writeAppGroupFlags(&drvConfIo->conf_group.log_conn, &drvConfIo->conf_group.fragment_bits, conf); + writeAppGroupFlags(&drvConfIo->conf_group.apply_child, &drvConfIo->conf_group.log_conn, + &drvConfIo->conf_group.fragment_bits, conf); writeLimits(drvConfIo->conf_group.limits, &drvConfIo->conf_group.limit_bits, &drvConfIo->conf_group.limit_2bits, conf.appGroups()); @@ -519,13 +524,17 @@ void ConfUtil::writeData(char *output, const FirewallConf &conf, drvConf->exe_apps_off = exeAppsOff; } -void ConfUtil::writeAppGroupFlags( - quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf) +void ConfUtil::writeAppGroupFlags(quint16 *applyChildBits, quint16 *logConnBits, + quint16 *fragmentBits, const FirewallConf &conf) { + *applyChildBits = 0; *logConnBits = 0; *fragmentBits = 0; int i = 0; for (const AppGroup *appGroup : conf.appGroups()) { + if (appGroup->applyChild()) { + *applyChildBits |= (1 << i); + } if (appGroup->logConn()) { *logConnBits |= (1 << i); } diff --git a/src/ui/util/conf/confutil.h b/src/ui/util/conf/confutil.h index fa1f5adb..954f9f5c 100644 --- a/src/ui/util/conf/confutil.h +++ b/src/ui/util/conf/confutil.h @@ -43,8 +43,8 @@ public slots: int write(const FirewallConf &conf, ConfAppsWalker *confAppsWalker, EnvManager &envManager, QByteArray &buf); int writeFlags(const FirewallConf &conf, QByteArray &buf); - int writeAppEntry(int groupIndex, bool useGroupPerm, bool blocked, bool alerted, bool isNew, - const QString &appPath, QByteArray &buf); + int writeAppEntry(int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, + bool alerted, bool isNew, const QString &appPath, QByteArray &buf); int writeVersion(QByteArray &buf); int writeZone(const Ip4Range &ip4Range, QByteArray &buf); int writeZones(quint32 zonesMask, quint32 enabledMask, quint32 dataSize, @@ -78,8 +78,8 @@ private: appentry_map_t &exeAppsMap, quint32 &wildAppsSize, quint32 &prefixAppsSize, quint32 &exeAppsSize); - bool addApp(int groupIndex, bool useGroupPerm, bool blocked, bool alerted, bool isNew, - const QString &appPath, appentry_map_t &appsMap, quint32 &appsSize, + bool addApp(int groupIndex, bool useGroupPerm, bool applyChild, bool blocked, bool alerted, + bool isNew, const QString &appPath, appentry_map_t &appsMap, quint32 &appsSize, bool canOverwrite = true); static QString parseAppPath(const StringView line, bool &isWild, bool &isPrefix); @@ -93,8 +93,8 @@ private: const appentry_map_t &wildAppsMap, const appentry_map_t &prefixAppsMap, const appentry_map_t &exeAppsMap); - static void writeAppGroupFlags( - quint16 *logConnBits, quint16 *fragmentBits, const FirewallConf &conf); + static void writeAppGroupFlags(quint16 *applyChildBits, quint16 *logConnBits, + quint16 *fragmentBits, const FirewallConf &conf); static void writeLimits(struct fort_traf *limits, quint16 *limitBits, quint32 *limit2Bits, const QList &appGroups);