mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
ui: fw rules improvements
- Fixed error validating some meta expressions. - Added option to enable/disable fw rules. - Limit fw rules deletion to 1 rule for now, until a bug is fixed.
This commit is contained in:
parent
d88a253d9c
commit
dd7476fe52
3 changed files with 58 additions and 24 deletions
|
@ -1,11 +1,10 @@
|
|||
|
||||
from PyQt5 import Qt, QtCore
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtGui import QStandardItemModel, QStandardItem
|
||||
from PyQt5.QtSql import QSqlQuery, QSqlError
|
||||
from PyQt5.QtWidgets import QTableView, QAbstractSlider, QItemDelegate, QAbstractItemView, QPushButton, QWidget, QVBoxLayout
|
||||
from PyQt5.QtCore import QItemSelectionModel, pyqtSignal, pyqtSlot, QEvent
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtCore import QCoreApplication as QC
|
||||
import math
|
||||
|
||||
from opensnitch.nodes import Nodes
|
||||
from opensnitch.firewall import Firewall
|
||||
|
@ -40,6 +39,7 @@ class FirewallTableModel(QStandardItemModel):
|
|||
COL_CHAIN_TABLE = 4
|
||||
COL_CHAIN_FAMILY = 5
|
||||
COL_CHAIN_HOOK = 6
|
||||
COL_ENABLED = 7
|
||||
|
||||
headersAll = [
|
||||
"", # buttons
|
||||
|
@ -294,4 +294,3 @@ class FirewallTableView(QTableView):
|
|||
self.model().columnCountChanged.connect(self._cb_column_count_changed)
|
||||
model.rowsUpdated.connect(self._cb_rows_updated)
|
||||
model.rowsReordered.connect(self._cb_rows_reordered)
|
||||
|
||||
|
|
|
@ -1166,7 +1166,7 @@ class FwRuleDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
("," not in statem_value and "-" not in statem_value):
|
||||
if not self._is_valid_int_value(statem_value):
|
||||
return None, None, None, QC.translate("firewall", "port not valid.")
|
||||
elif st_idx == self.STATM_CT_SET or st_idx == self.STATM_CT_MARK or self.STATM_META_SET_MARK:
|
||||
elif st_idx == self.STATM_CT_SET or st_idx == self.STATM_CT_MARK or st_idx == self.STATM_META_SET_MARK:
|
||||
if not self._is_valid_int_value(statem_value):
|
||||
return None, None, None, QC.translate("firewall", "Invalid value {0}, number expected.".format(statem_value))
|
||||
|
||||
|
|
|
@ -857,9 +857,14 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
selection = table.selectionModel().selectedRows()
|
||||
if not selection:
|
||||
return
|
||||
is_rule_enabled = model.index(selection[0].row(), FirewallTableModel.COL_ENABLED).data()
|
||||
|
||||
menu = QtWidgets.QMenu()
|
||||
actionsMenu = QtWidgets.QMenu(QC.translate("stats", "Action"))
|
||||
_label_enable = QC.translate("stats", "Disable")
|
||||
if is_rule_enabled == "False":
|
||||
_label_enable = QC.translate("stats", "Enable")
|
||||
_menu_enable = actionsMenu.addAction(_label_enable)
|
||||
_menu_delete = actionsMenu.addAction(QC.translate("stats", "Delete"))
|
||||
menu.addMenu(actionsMenu)
|
||||
|
||||
|
@ -871,6 +876,8 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
|
||||
if action == _menu_delete:
|
||||
self._table_menu_delete(cur_idx, model, selection)
|
||||
elif action == _menu_enable:
|
||||
self._table_menu_enable(cur_idx, model, selection, is_rule_enabled)
|
||||
|
||||
except Exception as e:
|
||||
print("fwrules contextual menu error:", e)
|
||||
|
@ -878,7 +885,6 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
self._clear_rows_selection()
|
||||
return True
|
||||
|
||||
|
||||
def _configure_rules_contextual_menu(self, pos):
|
||||
try:
|
||||
cur_idx = self.tabWidget.currentIndex()
|
||||
|
@ -1096,22 +1102,44 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
|
||||
def _table_menu_enable(self, cur_idx, model, selection, is_rule_enabled):
|
||||
rule_status = "False" if is_rule_enabled == "True" else "True"
|
||||
enable_rule = False if is_rule_enabled == "True" else True
|
||||
|
||||
for idx in selection:
|
||||
rule_name = model.index(idx.row(), self.COL_R_NAME).data()
|
||||
node_addr = model.index(idx.row(), self.COL_R_NODE).data()
|
||||
if cur_idx == self.TAB_RULES and not self.fwTable.isVisible():
|
||||
for idx in selection:
|
||||
rule_name = model.index(idx.row(), self.COL_R_NAME).data()
|
||||
node_addr = model.index(idx.row(), self.COL_R_NODE).data()
|
||||
|
||||
records = self._get_rule(rule_name, node_addr)
|
||||
rule = Rule.new_from_records(records)
|
||||
rule_type = ui_pb2.DISABLE_RULE if is_rule_enabled == "True" else ui_pb2.ENABLE_RULE
|
||||
records = self._get_rule(rule_name, node_addr)
|
||||
rule = Rule.new_from_records(records)
|
||||
rule_type = ui_pb2.DISABLE_RULE if is_rule_enabled == "True" else ui_pb2.ENABLE_RULE
|
||||
|
||||
self._db.update(table="rules", fields="enabled=?",
|
||||
values=[rule_status], condition="name='{0}' AND node='{1}'".format(rule_name, node_addr),
|
||||
action_on_conflict="")
|
||||
self._db.update(table="rules", fields="enabled=?",
|
||||
values=[rule_status], condition="name='{0}' AND node='{1}'".format(rule_name, node_addr),
|
||||
action_on_conflict="")
|
||||
|
||||
noti = ui_pb2.Notification(type=rule_type, rules=[rule])
|
||||
nid = self._nodes.send_notification(node_addr, noti, self._notification_callback)
|
||||
if nid != None:
|
||||
noti = ui_pb2.Notification(type=rule_type, rules=[rule])
|
||||
nid = self._nodes.send_notification(node_addr, noti, self._notification_callback)
|
||||
if nid != None:
|
||||
self._notifications_sent[nid] = noti
|
||||
|
||||
elif cur_idx == self.TAB_RULES and self.fwTable.isVisible():
|
||||
nodes_updated = []
|
||||
for idx in selection:
|
||||
uuid = model.index(idx.row(), FirewallTableModel.COL_UUID).data()
|
||||
node = model.index(idx.row(), FirewallTableModel.COL_ADDR).data()
|
||||
addr, chain = self._fw.get_rule_by_uuid(uuid)
|
||||
if chain is None:
|
||||
print("error, rule not found by uuid:", uuid, "node:", node, "row:", idx.row())
|
||||
continue
|
||||
|
||||
chain.Rules[0].Enabled = enable_rule
|
||||
updated, err = self._fw.update_rule(addr, uuid, chain)
|
||||
if updated:
|
||||
nodes_updated.append(addr)
|
||||
|
||||
for addr in nodes_updated:
|
||||
node = self._nodes.get_node(addr)
|
||||
nid, noti = self._nodes.reload_fw(addr, node['firewall'], self._notification_callback)
|
||||
self._notifications_sent[nid] = noti
|
||||
|
||||
def _table_menu_delete(self, cur_idx, model, selection):
|
||||
|
@ -1129,16 +1157,23 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
return False
|
||||
|
||||
if cur_idx == self.TAB_RULES and self.fwTable.isVisible():
|
||||
do_refresh = False
|
||||
nodes_updated = {}
|
||||
for idx in selection:
|
||||
uuid = model.index(idx.row(), 1).data()
|
||||
node = model.index(idx.row(), 2).data()
|
||||
uuid = model.index(idx.row(), FirewallTableModel.COL_UUID).data()
|
||||
node = model.index(idx.row(), FirewallTableModel.COL_ADDR).data()
|
||||
ok, fw_config = self._fw.delete_rule(node, uuid)
|
||||
do_refresh |= ok
|
||||
if ok:
|
||||
nodes_updated[node] = fw_config
|
||||
else:
|
||||
print("del not ok:", uuid)
|
||||
|
||||
if do_refresh:
|
||||
nid, noti = self._nodes.reload_fw(node, fw_config, self._notification_callback)
|
||||
# FIXME: deleting multiple rules does not work as expected yet.
|
||||
break
|
||||
|
||||
for addr in nodes_updated:
|
||||
nid, noti = self._nodes.reload_fw(addr, nodes_updated[addr], self._notification_callback)
|
||||
self._notifications_sent[nid] = noti
|
||||
|
||||
elif cur_idx == self.TAB_RULES and not self.fwTable.isVisible():
|
||||
for idx in selection:
|
||||
name = model.index(idx.row(), self.COL_R_NAME).data()
|
||||
|
|
Loading…
Add table
Reference in a new issue