UI: Programs: Add "Kill Process" option

This commit is contained in:
Nodir Temirkhodjaev 2023-05-01 14:03:15 +03:00
parent 194bfb825d
commit efebf6b2c0
13 changed files with 97 additions and 48 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -16,6 +16,7 @@ public:
bool logBlocked = true;
bool logConn = true;
bool blocked = false;
bool killProcess = false;
bool alerted = false;
int groupIndex = 0;

View File

@ -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<walkAppsCallback> &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;

View File

@ -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<walkAppsCallback> &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);

View File

@ -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

View File

@ -83,6 +83,7 @@ void ProgramEditDialog::initialize(const AppRow &appRow, const QVector<qint64> &
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();

View File

@ -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;

View File

@ -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";

View File

@ -19,7 +19,8 @@ bool ConfManagerRpc::addApp(const App &app)
{
return IoC<RpcManager>()->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<RpcManager>()->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<RpcManager>()->doOnServer(
Control::Rpc_ConfManager_updateAppBlocked, { appId, blocked });
Control::Rpc_ConfManager_updateAppBlocked, { appId, blocked, killProcess });
}
bool ConfManagerRpc::updateAppName(qint64 appId, const QString &appName)

View File

@ -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;

View File

@ -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(

View File

@ -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;