Skip to content

Commit

Permalink
UI: added dialog to add/modify rules from the UI
Browse files Browse the repository at this point in the history
Allow to add or modify rules from the UI.

The rules of all nodes are listed in the tab Rules.
Clicking on the name of the rule will display the connections that
matched the rule.

In this view 2 buttons are displayed: edit rule and delete rule.

Editing a rule will edit the rule for a particular node. If you want
the changes to be applied to all nodes you have to select that option.

All fields can have a regular expression. If the regular expression is
not valid, a message will be displayed on the dialog.

If the rule is applied correctly, "Rule applied" will be shown.
Otherwise an error will appear.

Bear in mind that this still a WIP commit. Bugs and errors will
appear that we'll have to fix.
  • Loading branch information
gustavo-iniguez-goya committed May 10, 2020
1 parent f1fd7a0 commit 53aa721
Show file tree
Hide file tree
Showing 11 changed files with 1,111 additions and 272 deletions.
43 changes: 37 additions & 6 deletions ui/opensnitch/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,20 @@ def _create_tables(self):
"process text, " \
"process_args text, " \
"rule text, " \
"UNIQUE(time, node, action, protocol, src_ip, src_port, dst_ip, dst_port, uid, pid, process, process_args))",
"UNIQUE(node, action, protocol, src_ip, src_port, dst_ip, dst_port, uid, pid, process, process_args))",
self.db)
q.exec_()
q = QSqlQuery("create table if not exists rules (" \
"time text, "\
"name text primary key, "\
"time text, " \
"node text, " \
"name text, " \
"enabled text, " \
"action text, " \
"duration text, " \
"operator text " \
"operator_type text, " \
"operator_operand text, " \
"operator_data text, " \
"UNIQUE(node, name)"
")", self.db)
q.exec_()
q = QSqlQuery("create table if not exists hosts (what text primary key, hits integer)", self.db)
Expand Down Expand Up @@ -119,6 +124,27 @@ def commit(self):
def rollback(self):
self.db.rollback()

def select(self, qstr):
try:
return QSqlQuery(qstr, self.db)
except Exception as e:
print("db, select() exception: ", e)

return None

def remove(self, qstr):
try:
q = QSqlQuery(qstr, self.db)
if q.exec_():
return True
else:
print("db, remove() ERROR: ", qstr)
print(q.lastError().driverText())
except Exception as e:
print("db, remove exception: ", e)

return False

def _insert(self, query_str, columns):
with self._lock:
try:
Expand All @@ -127,14 +153,19 @@ def _insert(self, query_str, columns):
q.prepare(query_str)
for idx, v in enumerate(columns):
q.bindValue(idx, v)
if not q.exec_():
if q.exec_():
return True
else:
print("_insert() ERROR", query_str)
print(q.lastError().driverText())

except Exception as e:
print("_insert exception", e)
finally:
q.finish()

return False

def insert(self, table, fields, columns, update_field=None, update_value=None, action_on_conflict="REPLACE"):
if update_field != None:
action_on_conflict = ""
Expand All @@ -153,7 +184,7 @@ def insert(self, table, fields, columns, update_field=None, update_value=None, a
update_fields + \
" WHERE " + update_field + "=excluded." + update_field

self._insert(qstr, columns)
return self._insert(qstr, columns)

def update(self, table, fields, values, action_on_conflict="OR IGNORE"):
qstr = "UPDATE " + action_on_conflict + " " + table + " SET " + fields
Expand Down
3 changes: 1 addition & 2 deletions ui/opensnitch/dialogs/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):

LOG_TAG = "[Preferences] "
_notification_trigger = QtCore.pyqtSignal(str, ui_pb2.Notification)

def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowStaysOnTopHint)
Expand Down Expand Up @@ -130,14 +129,14 @@ def _save_settings(self):
addr = self._nodes_combo.currentText()
if (self._node_needs_update or self._node_apply_all_check.isChecked()) and addr != "":
try:
# TODO: move to Nodes()
node_config = "{\"DefaultAction\": \"" + self._node_action_combo.currentText() + "\"" \
+ ", \"DefaultDuration\": \"" + self._node_duration_combo.currentText() + "\"" \
+ ", \"ProcMonitorMethod\": \"" + self._node_monitor_method_combo.currentText() + "\"" \
+ ", \"InterceptUnknown\": " + str(self._node_intercept_unknown_check.isChecked()).lower() \
+ ", \"LogLevel\": " + str(self._node_loglevel_combo.currentIndex()) \
+ "}"
notif = ui_pb2.Notification(
id=int(str(time.time()).replace(".", "")),
type=ui_pb2.CHANGE_CONFIG,
data=node_config,
rules=[])
Expand Down
2 changes: 2 additions & 0 deletions ui/opensnitch/dialogs/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ def _get_combo_operator(self, combo, what_idx):
def _on_apply_clicked(self):
self._cfg.setSettings("promptDialog/geometry", self.saveGeometry())
self._rule = ui_pb2.Rule(name="user.choice")
self._rule.enabled = True

if self._action_combo.currentIndex() == 0:
self._rule.action = "allow"
Expand Down Expand Up @@ -360,6 +361,7 @@ def _on_apply_clicked(self):
self._rule.operator.operand = ""

self._rule.name = slugify("%s %s %s" % (self._rule.action, self._rule.operator.type, self._rule.operator.data))

self.hide()
if self._is_advanced_checked:
self._advanced_check.toggle()
Expand Down
Loading

0 comments on commit 53aa721

Please sign in to comment.