diff --git a/src/driver/common/fortconf.h b/src/driver/common/fortconf.h index 3b9bc729..cac4f4b0 100644 --- a/src/driver/common/fortconf.h +++ b/src/driver/common/fortconf.h @@ -158,7 +158,7 @@ typedef struct fort_app_flags struct { UINT16 group_index : 5; - /* UINT16 reserved : 2; */ + /* UINT16 reserved : 1; */ UINT16 use_group_perm : 1; UINT16 apply_child : 1; @@ -167,6 +167,7 @@ typedef struct fort_app_flags UINT16 log_conn : 1; UINT16 blocked : 1; + UINT16 kill_process : 1; UINT16 alerted : 1; UINT16 is_new : 1; UINT16 found : 1; diff --git a/src/ui/conf/app.cpp b/src/ui/conf/app.cpp index 342897fa..561ecc3f 100644 --- a/src/ui/conf/app.cpp +++ b/src/ui/conf/app.cpp @@ -4,5 +4,6 @@ bool App::isEqual(const App &o) const { return useGroupPerm == o.useGroupPerm && applyChild == o.applyChild && lanOnly == o.lanOnly && logBlocked == o.logBlocked && logConn == o.logConn && blocked == o.blocked - && groupIndex == o.groupIndex && appPath == o.appPath && endTime == o.endTime; + && killProcess == o.killProcess && groupIndex == o.groupIndex && appPath == o.appPath + && endTime == o.endTime; } diff --git a/src/ui/conf/app.h b/src/ui/conf/app.h index 1bfa1c58..5904f15e 100644 --- a/src/ui/conf/app.h +++ b/src/ui/conf/app.h @@ -16,6 +16,7 @@ public: bool logBlocked = true; bool logConn = true; bool blocked = false; + bool killProcess = false; bool alerted = false; int groupIndex = 0; diff --git a/src/ui/conf/confmanager.cpp b/src/ui/conf/confmanager.cpp index 15c71c8d..62b5d0c8 100644 --- a/src/ui/conf/confmanager.cpp +++ b/src/ui/conf/confmanager.cpp @@ -36,7 +36,7 @@ namespace { const QLoggingCategory LC("conf"); -constexpr int DATABASE_USER_VERSION = 18; +constexpr int DATABASE_USER_VERSION = 19; constexpr int APP_END_TIMER_INTERVAL_MIN = 100; constexpr int APP_END_TIMER_INTERVAL_MAX = 24 * 60 * 60 * 1000; // 1 day @@ -122,6 +122,7 @@ const char *const sqlSelectAppById = "SELECT" " t.log_blocked," " t.log_conn," " t.blocked," + " t.kill_process," " (alert.app_id IS NOT NULL) as alerted" " FROM app t" " JOIN app_group g ON g.app_group_id = t.app_group_id" @@ -137,6 +138,7 @@ const char *const sqlSelectApps = "SELECT" " t.log_blocked," " t.log_conn," " t.blocked," + " t.kill_process," " (alert.app_id IS NOT NULL) as alerted" " FROM app t" " JOIN app_group g ON g.app_group_id = t.app_group_id" @@ -156,14 +158,15 @@ 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, apply_child, lan_only," - " log_blocked, log_conn, blocked," + " log_blocked, log_conn, blocked, kill_process," " creat_time, end_time)" - " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)" + " VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)" " ON CONFLICT(path) DO UPDATE" " SET app_group_id = ?1, name = ?3," " use_group_perm = ?4, apply_child = ?5," " lan_only = ?6, log_blocked = ?7, log_conn = ?8," - " blocked = ?9, creat_time = ?10, end_time = ?11" + " blocked = ?9, kill_process = ?10," + " creat_time = ?10, end_time = ?11" " RETURNING app_id;"; const char *const sqlInsertAppAlert = "INSERT INTO app_alert(app_id) VALUES(?1);"; @@ -176,12 +179,13 @@ const char *const sqlUpdateApp = "UPDATE app" " SET app_group_id = ?2, name = ?3, use_group_perm = ?4," " apply_child = ?5, lan_only = ?6," " log_blocked = ?7, log_conn = ?8," - " blocked = ?9, end_time = ?10" + " blocked = ?9, kill_process = ?10, end_time = ?11" " WHERE app_id = ?1;"; const char *const sqlUpdateAppName = "UPDATE app SET name = ?2 WHERE app_id = ?1;"; -const char *const sqlUpdateAppBlocked = "UPDATE app SET blocked = ?2, end_time = NULL" +const char *const sqlUpdateAppBlocked = "UPDATE app SET blocked = ?2, kill_process = ?3," + " end_time = NULL" " WHERE app_id = ?1;"; const char *const sqlUpdateAppResetGroup = "UPDATE app" @@ -847,7 +851,7 @@ bool ConfManager::updateApp(const App &app) const auto vars = QVariantList() << app.appId << appGroup->id() << app.appName << app.useGroupPerm << app.applyChild - << app.lanOnly << app.logBlocked << app.logConn << app.blocked + << app.lanOnly << app.logBlocked << app.logConn << app.blocked << app.killProcess << (!app.endTime.isNull() ? app.endTime : QVariant()); sqliteDb()->executeEx(sqlUpdateApp, vars, 0, &ok); @@ -868,17 +872,17 @@ bool ConfManager::updateApp(const App &app) return ok; } -bool ConfManager::updateAppBlocked(qint64 appId, bool blocked) +bool ConfManager::updateAppBlocked(qint64 appId, bool blocked, bool killProcess) { bool changed = false; - if (!updateDriverAppBlocked(appId, blocked, changed)) + if (!updateDriverAppBlocked(appId, blocked, killProcess, changed)) return false; bool ok = true; sqliteDb()->beginTransaction(); - const auto vars = QVariantList() << appId << blocked; + const auto vars = QVariantList() << appId << blocked << killProcess; if (changed) { sqliteDb()->executeEx(sqlUpdateAppBlocked, vars, 0, &ok); @@ -929,7 +933,8 @@ bool ConfManager::walkApps(const std::function &func) app.logBlocked = stmt.columnBool(5); app.logConn = stmt.columnBool(6); app.blocked = stmt.columnBool(7); - app.alerted = stmt.columnBool(8); + app.killProcess = stmt.columnBool(8); + app.alerted = stmt.columnBool(9); if (!func(app)) return false; @@ -958,6 +963,7 @@ void ConfManager::updateAppEndTimes() app.logBlocked = stmt.columnBool(7); app.logConn = stmt.columnBool(8); app.blocked = true; + app.killProcess = false; updateApp(app); } @@ -1188,7 +1194,7 @@ bool ConfManager::addOrUpdateApp(const App &app) const auto vars = QVariantList() << appGroup->id() << app.appPath << app.appName << app.useGroupPerm << app.applyChild - << app.lanOnly << app.logBlocked << app.logConn << app.blocked + << app.lanOnly << app.logBlocked << app.logConn << app.blocked << app.killProcess << QDateTime::currentDateTime() << (!app.endTime.isNull() ? app.endTime : QVariant()); const auto appIdVar = sqliteDb()->executeEx(sqlUpsertApp, vars, 1, &ok); @@ -1212,7 +1218,8 @@ bool ConfManager::addOrUpdateApp(const App &app) return ok; } -bool ConfManager::updateDriverAppBlocked(qint64 appId, bool blocked, bool &changed) +bool ConfManager::updateDriverAppBlocked( + qint64 appId, bool blocked, bool killProcess, bool &changed) { SqliteStmt stmt; if (!sqliteDb()->prepare(stmt, sqlSelectAppById)) @@ -1231,10 +1238,12 @@ bool ConfManager::updateDriverAppBlocked(qint64 appId, bool blocked, bool &chang app.logBlocked = stmt.columnBool(5); app.logConn = stmt.columnBool(6); app.blocked = stmt.columnBool(7); - const bool wasAlerted = stmt.columnBool(8); + app.killProcess = stmt.columnBool(8); + const bool wasAlerted = stmt.columnBool(9); - if (blocked != app.blocked || wasAlerted) { + if (blocked != app.blocked || killProcess != app.killProcess || wasAlerted) { app.blocked = blocked; + app.killProcess = killProcess; if (!updateDriverUpdateApp(app)) return false; diff --git a/src/ui/conf/confmanager.h b/src/ui/conf/confmanager.h index 3d16f686..c9e93d6c 100644 --- a/src/ui/conf/confmanager.h +++ b/src/ui/conf/confmanager.h @@ -67,7 +67,7 @@ public: virtual bool deleteApp(qint64 appId); virtual bool purgeApps(); virtual bool updateApp(const App &app); - virtual bool updateAppBlocked(qint64 appId, bool blocked); + virtual bool updateAppBlocked(qint64 appId, bool blocked, bool killProcess = false); virtual bool updateAppName(qint64 appId, const QString &appName); bool walkApps(const std::function &func) override; @@ -118,7 +118,7 @@ private: void emitAppUpdated(); bool addOrUpdateApp(const App &app); - bool updateDriverAppBlocked(qint64 appId, bool blocked, bool &changed); + bool updateDriverAppBlocked(qint64 appId, bool blocked, bool killProcess, bool &changed); bool validateConf(const FirewallConf &newConf); diff --git a/src/ui/conf/migrations/1.sql b/src/ui/conf/migrations/1.sql index c07eae93..58ee699f 100644 --- a/src/ui/conf/migrations/1.sql +++ b/src/ui/conf/migrations/1.sql @@ -130,6 +130,7 @@ CREATE TABLE app( log_blocked BOOLEAN NOT NULL DEFAULT 1, log_conn BOOLEAN NOT NULL DEFAULT 1, blocked BOOLEAN NOT NULL, + kill_process BOOLEAN NOT NULL DEFAULT 0, creat_time INTEGER NOT NULL, end_time INTEGER, policy_id INTEGER diff --git a/src/ui/form/prog/programeditdialog.cpp b/src/ui/form/prog/programeditdialog.cpp index a03f2291..62720905 100644 --- a/src/ui/form/prog/programeditdialog.cpp +++ b/src/ui/form/prog/programeditdialog.cpp @@ -83,6 +83,7 @@ void ProgramEditDialog::initialize(const AppRow &appRow, const QVector & m_cbLogConn->setChecked(appRow.logConn); m_rbAllowApp->setChecked(!appRow.blocked); m_rbBlockApp->setChecked(appRow.blocked); + m_rbKillProcess->setChecked(appRow.killProcess); m_cscBlockAppIn->checkBox()->setChecked(false); m_cscBlockAppIn->spinBox()->setValue(1); m_cbBlockAppAt->setChecked(!appRow.endTime.isNull()); @@ -129,6 +130,7 @@ void ProgramEditDialog::retranslateUi() m_rbAllowApp->setText(tr("Allow")); m_rbBlockApp->setText(tr("Block")); + m_rbKillProcess->setText(tr("Kill Process")); m_cscBlockAppIn->checkBox()->setText(tr("Block In:")); retranslateAppBlockInHours(); @@ -347,8 +349,12 @@ QLayout *ProgramEditDialog::setupAllowLayout() m_rbBlockApp = new QRadioButton(); m_rbBlockApp->setIcon(IconCache::icon(":/icons/deny.png")); + m_rbKillProcess = new QRadioButton(); + m_rbKillProcess->setIcon(IconCache::icon(":/icons/cancel.png")); + allowLayout->addWidget(m_rbAllowApp, 1, Qt::AlignRight); - allowLayout->addWidget(m_rbBlockApp, 1, Qt::AlignLeft); + allowLayout->addWidget(m_rbBlockApp, 1, Qt::AlignHCenter); + allowLayout->addWidget(m_rbKillProcess, 1, Qt::AlignLeft); // Block after N hours m_cscBlockAppIn = new CheckSpinCombo(); @@ -466,7 +472,8 @@ void ProgramEditDialog::fillApp(App &app) const app.lanOnly = m_cbLanOnly->isChecked(); app.logBlocked = m_cbLogBlocked->isChecked(); app.logConn = m_cbLogConn->isChecked(); - app.blocked = m_rbBlockApp->isChecked(); + app.blocked = !m_rbAllowApp->isChecked(); + app.killProcess = m_rbKillProcess->isChecked(); app.groupIndex = m_comboAppGroup->currentIndex(); app.appPath = m_editPath->text(); app.appName = m_editName->text(); diff --git a/src/ui/form/prog/programeditdialog.h b/src/ui/form/prog/programeditdialog.h index be4d9f03..1843ef81 100644 --- a/src/ui/form/prog/programeditdialog.h +++ b/src/ui/form/prog/programeditdialog.h @@ -78,6 +78,7 @@ private: QCheckBox *m_cbLogConn = nullptr; QRadioButton *m_rbAllowApp = nullptr; QRadioButton *m_rbBlockApp = nullptr; + QRadioButton *m_rbKillProcess = nullptr; CheckSpinCombo *m_cscBlockAppIn = nullptr; QCheckBox *m_cbBlockAppAt = nullptr; QDateTimeEdit *m_dteBlockAppAt = nullptr; diff --git a/src/ui/model/applistmodel.cpp b/src/ui/model/applistmodel.cpp index 5620808e..d1ed8454 100644 --- a/src/ui/model/applistmodel.cpp +++ b/src/ui/model/applistmodel.cpp @@ -22,8 +22,29 @@ namespace { const auto alertColor = QColor("orange"); const auto allowColor = QColor("green"); const auto blockColor = QColor("red"); +const auto killProcessColor = QColor("magenta"); const auto inactiveColor = QColor("slategray"); +QString appStateIconPath(const AppRow &appRow) +{ + if (appRow.alerted) + return ":/icons/error.png"; + + if (appRow.killProcess) + return ":/icons/cancel.png"; + + if (appRow.blocked) + return ":/icons/deny.png"; + + if (!appRow.endTime.isNull()) + return ":/icons/time.png"; + + if (appRow.lanOnly) + return ":/icons/hostname.png"; + + return ":/icons/accept.png"; +} + } AppListModel::AppListModel(QObject *parent) : TableSqlModel(parent) { } @@ -231,6 +252,9 @@ QVariant AppListModel::appGroupColor(const AppRow &appRow) const QString AppListModel::appStateText(const AppRow &appRow) { + if (appRow.killProcess) + return tr("Kill Process"); + if (appRow.blocked) return tr("Block"); @@ -239,6 +263,9 @@ QString AppListModel::appStateText(const AppRow &appRow) QColor AppListModel::appStateColor(const AppRow &appRow) { + if (appRow.killProcess) + return killProcessColor; + if (appRow.blocked) return blockColor; @@ -247,13 +274,7 @@ QColor AppListModel::appStateColor(const AppRow &appRow) QIcon AppListModel::appStateIcon(const AppRow &appRow) { - return IconCache::icon(appRow.alerted - ? ":/icons/error.png" - : (appRow.blocked ? ":/icons/deny.png" - : (appRow.endTime.isNull() - ? (appRow.lanOnly ? ":/icons/hostname.png" - : ":/icons/accept.png") - : ":/icons/time.png"))); + return IconCache::icon(appStateIconPath(appRow)); } bool AppListModel::updateAppRow(const QString &sql, const QVariantList &vars, AppRow &appRow) const @@ -274,9 +295,10 @@ bool AppListModel::updateAppRow(const QString &sql, const QVariantList &vars, Ap appRow.logBlocked = stmt.columnBool(7); appRow.logConn = stmt.columnBool(8); appRow.blocked = stmt.columnBool(9); - appRow.alerted = stmt.columnBool(10); - appRow.endTime = stmt.columnDateTime(11); - appRow.creatTime = stmt.columnDateTime(12); + appRow.killProcess = stmt.columnBool(10); + appRow.alerted = stmt.columnBool(11); + appRow.endTime = stmt.columnDateTime(12); + appRow.creatTime = stmt.columnDateTime(13); return true; } @@ -322,6 +344,7 @@ QString AppListModel::sqlBase() const " t.log_blocked," " t.log_conn," " t.blocked," + " t.kill_process," " (alert.app_id IS NOT NULL) as alerted," " t.end_time," " t.creat_time" @@ -338,7 +361,7 @@ QString AppListModel::sqlOrderColumn() const columnsStr = "4 " + sqlOrderAsc() + ", 3"; break; case 1: // State - columnsStr = "11 DESC, 10 " + sqlOrderAsc() + ", 1"; + columnsStr = "12 DESC, 11, 10 " + sqlOrderAsc() + ", 1"; break; case 2: // Group columnsStr = "2"; diff --git a/src/ui/rpc/confmanagerrpc.cpp b/src/ui/rpc/confmanagerrpc.cpp index a143b725..a6c735b6 100644 --- a/src/ui/rpc/confmanagerrpc.cpp +++ b/src/ui/rpc/confmanagerrpc.cpp @@ -19,7 +19,8 @@ bool ConfManagerRpc::addApp(const App &app) { return IoC()->doOnServer(Control::Rpc_ConfManager_addApp, { app.useGroupPerm, app.applyChild, app.lanOnly, app.logBlocked, app.logConn, - app.blocked, app.groupIndex, app.appPath, app.appName, app.endTime }); + app.blocked, app.killProcess, app.groupIndex, app.appPath, app.appName, + app.endTime }); } bool ConfManagerRpc::deleteApp(qint64 appId) @@ -36,14 +37,14 @@ bool ConfManagerRpc::updateApp(const App &app) { return IoC()->doOnServer(Control::Rpc_ConfManager_updateApp, { app.useGroupPerm, app.applyChild, app.lanOnly, app.logBlocked, app.logConn, - app.blocked, app.groupIndex, app.appId, app.appPath, app.appName, - app.endTime }); + app.blocked, app.killProcess, app.groupIndex, app.appId, app.appPath, + app.appName, app.endTime }); } -bool ConfManagerRpc::updateAppBlocked(qint64 appId, bool blocked) +bool ConfManagerRpc::updateAppBlocked(qint64 appId, bool blocked, bool killProcess) { return IoC()->doOnServer( - Control::Rpc_ConfManager_updateAppBlocked, { appId, blocked }); + Control::Rpc_ConfManager_updateAppBlocked, { appId, blocked, killProcess }); } bool ConfManagerRpc::updateAppName(qint64 appId, const QString &appName) diff --git a/src/ui/rpc/confmanagerrpc.h b/src/ui/rpc/confmanagerrpc.h index 30136c9d..3bde541f 100644 --- a/src/ui/rpc/confmanagerrpc.h +++ b/src/ui/rpc/confmanagerrpc.h @@ -17,7 +17,7 @@ public: bool deleteApp(qint64 appId) override; bool purgeApps() override; bool updateApp(const App &app) override; - bool updateAppBlocked(qint64 appId, bool blocked) override; + bool updateAppBlocked(qint64 appId, bool blocked, bool killProcess = false) override; bool updateAppName(qint64 appId, const QString &appName) override; bool addZone(Zone &zone) override; diff --git a/src/ui/rpc/rpcmanager.cpp b/src/ui/rpc/rpcmanager.cpp index 90e8e425..1f3a1001 100644 --- a/src/ui/rpc/rpcmanager.cpp +++ b/src/ui/rpc/rpcmanager.cpp @@ -72,10 +72,11 @@ bool processConfManager_addApp( app.logBlocked = p.args.value(3).toBool(); app.logConn = p.args.value(4).toBool(); app.blocked = p.args.value(5).toBool(); - app.groupIndex = p.args.value(6).toInt(); - app.appPath = p.args.value(7).toString(); - app.appName = p.args.value(8).toString(); - app.endTime = p.args.value(9).toDateTime(); + app.killProcess = p.args.value(6).toBool(); + app.groupIndex = p.args.value(7).toInt(); + app.appPath = p.args.value(8).toString(); + app.appName = p.args.value(9).toString(); + app.endTime = p.args.value(10).toDateTime(); return confManager->addApp(app); } @@ -102,11 +103,12 @@ bool processConfManager_updateApp( app.logBlocked = p.args.value(3).toBool(); app.logConn = p.args.value(4).toBool(); app.blocked = p.args.value(5).toBool(); - app.groupIndex = p.args.value(6).toInt(); - app.appId = p.args.value(7).toLongLong(); - app.appPath = p.args.value(8).toString(); - app.appName = p.args.value(9).toString(); - app.endTime = p.args.value(10).toDateTime(); + app.killProcess = p.args.value(6).toBool(); + app.groupIndex = p.args.value(7).toInt(); + app.appId = p.args.value(8).toLongLong(); + app.appPath = p.args.value(9).toString(); + app.appName = p.args.value(10).toString(); + app.endTime = p.args.value(11).toDateTime(); return confManager->updateApp(app); } @@ -114,7 +116,8 @@ bool processConfManager_updateApp( bool processConfManager_updateAppBlocked( ConfManager *confManager, const ProcessCommandArgs &p, QVariantList & /*resArgs*/) { - return confManager->updateAppBlocked(p.args.value(0).toLongLong(), p.args.value(1).toBool()); + return confManager->updateAppBlocked( + p.args.value(0).toLongLong(), p.args.value(1).toBool(), p.args.value(2).toBool()); } bool processConfManager_updateAppName( diff --git a/src/ui/util/conf/confutil.cpp b/src/ui/util/conf/confutil.cpp index 1162920e..851ac3ef 100644 --- a/src/ui/util/conf/confutil.cpp +++ b/src/ui/util/conf/confutil.cpp @@ -474,6 +474,7 @@ bool ConfUtil::addApp( appEntry.flags.log_blocked = app.logBlocked; appEntry.flags.log_conn = app.logConn; appEntry.flags.blocked = app.blocked; + appEntry.flags.kill_process = app.killProcess; appEntry.flags.alerted = app.alerted; appEntry.flags.is_new = isNew; appEntry.flags.found = 1;