mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
ui,popups: allow to update checksums
When the checksum of a binary changes, due to an update or something else, you'll be prompted to allow the outbound connection if the previous checksum of the rule doesn't match the new one. Without a visual warning was almost impossible to know what was going on. Besides, you had to dismiss that pop-up, find the rule, and update the checksum. Now there's a warning message, and you can update the rule from the pop-up. Related: #413
This commit is contained in:
parent
ffd70836f6
commit
02cf65ac33
4 changed files with 380 additions and 137 deletions
|
@ -584,6 +584,25 @@ class Database:
|
||||||
|
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
def get_rule_by_field(self, node_addr=None, field=None, value=None):
|
||||||
|
"""
|
||||||
|
get rule records by field (process.path, etc)
|
||||||
|
"""
|
||||||
|
qstr = "SELECT * FROM rules WHERE {0} LIKE ?".format(field)
|
||||||
|
q = QSqlQuery(qstr, self.db)
|
||||||
|
if node_addr != None:
|
||||||
|
qstr = qstr + " AND node=?".format(node_addr)
|
||||||
|
|
||||||
|
q.prepare(qstr)
|
||||||
|
q.addBindValue("%" + value + "%")
|
||||||
|
if node_addr != None:
|
||||||
|
q.addBindValue(node_addr)
|
||||||
|
if not q.exec_():
|
||||||
|
print("get_rule_by_field() error:", q.lastError().driverText())
|
||||||
|
return None
|
||||||
|
|
||||||
|
return q
|
||||||
|
|
||||||
def get_rules(self, node_addr):
|
def get_rules(self, node_addr):
|
||||||
"""
|
"""
|
||||||
get rule records, given the name of the rule and the node
|
get rule records, given the name of the rule and the node
|
||||||
|
|
|
@ -19,6 +19,7 @@ from opensnitch.config import Config
|
||||||
from opensnitch.version import version
|
from opensnitch.version import version
|
||||||
from opensnitch.actions import Actions
|
from opensnitch.actions import Actions
|
||||||
from opensnitch.rules import Rules, Rule
|
from opensnitch.rules import Rules, Rule
|
||||||
|
from opensnitch.nodes import Nodes
|
||||||
|
|
||||||
from opensnitch import ui_pb2
|
from opensnitch import ui_pb2
|
||||||
|
|
||||||
|
@ -28,6 +29,10 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
_tick_trigger = QtCore.pyqtSignal()
|
_tick_trigger = QtCore.pyqtSignal()
|
||||||
_timeout_trigger = QtCore.pyqtSignal()
|
_timeout_trigger = QtCore.pyqtSignal()
|
||||||
|
|
||||||
|
PAGE_MAIN = 2
|
||||||
|
PAGE_DETAILS = 0
|
||||||
|
PAGE_CHECKSUMS = 1
|
||||||
|
|
||||||
DEFAULT_TIMEOUT = 15
|
DEFAULT_TIMEOUT = 15
|
||||||
|
|
||||||
# don't translate
|
# don't translate
|
||||||
|
@ -59,6 +64,7 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
# Other interesting flags: QtCore.Qt.Tool | QtCore.Qt.BypassWindowManagerHint
|
# Other interesting flags: QtCore.Qt.Tool | QtCore.Qt.BypassWindowManagerHint
|
||||||
self._cfg = Config.get()
|
self._cfg = Config.get()
|
||||||
self._rules = Rules.instance()
|
self._rules = Rules.instance()
|
||||||
|
self._nodes = Nodes.instance()
|
||||||
|
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.setWindowIcon(appicon)
|
self.setWindowIcon(appicon)
|
||||||
|
@ -108,6 +114,10 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
self.cmdInfo.clicked.connect(self._cb_cmdinfo_clicked)
|
self.cmdInfo.clicked.connect(self._cb_cmdinfo_clicked)
|
||||||
self.cmdBack.clicked.connect(self._cb_cmdback_clicked)
|
self.cmdBack.clicked.connect(self._cb_cmdback_clicked)
|
||||||
|
|
||||||
|
self.cmdUpdateRule.clicked.connect(self._cb_update_rule_clicked)
|
||||||
|
self.cmdBackChecksums.clicked.connect(self._cb_cmdback_clicked)
|
||||||
|
self.messageLabel.linkActivated.connect(self._cb_warninglbl_clicked)
|
||||||
|
|
||||||
self.allowIcon = Icons.new(self, "emblem-default")
|
self.allowIcon = Icons.new(self, "emblem-default")
|
||||||
denyIcon = Icons.new(self, "emblem-important")
|
denyIcon = Icons.new(self, "emblem-important")
|
||||||
rejectIcon = Icons.new(self, "window-close")
|
rejectIcon = Icons.new(self, "window-close")
|
||||||
|
@ -116,6 +126,7 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
|
|
||||||
self.cmdInfo.setIcon(infoIcon)
|
self.cmdInfo.setIcon(infoIcon)
|
||||||
self.cmdBack.setIcon(backIcon)
|
self.cmdBack.setIcon(backIcon)
|
||||||
|
self.cmdBackChecksums.setIcon(backIcon)
|
||||||
|
|
||||||
self._default_action = self._cfg.getInt(self._cfg.DEFAULT_ACTION_KEY)
|
self._default_action = self._cfg.getInt(self._cfg.DEFAULT_ACTION_KEY)
|
||||||
|
|
||||||
|
@ -197,7 +208,7 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
self.checkSum.setVisible(self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] != "" and state)
|
self.checkSum.setVisible(self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] != "" and state)
|
||||||
self.checksumLabel_2.setVisible(self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] != "" and state)
|
self.checksumLabel_2.setVisible(self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] != "" and state)
|
||||||
self.checksumLabel.setVisible(self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] != "" and state)
|
self.checksumLabel.setVisible(self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] != "" and state)
|
||||||
self.stackedWidget.setCurrentIndex(1)
|
self.stackedWidget.setCurrentIndex(self.PAGE_MAIN)
|
||||||
|
|
||||||
self._ischeckAdvanceded = state
|
self._ischeckAdvanceded = state
|
||||||
self.adjust_size()
|
self.adjust_size()
|
||||||
|
@ -206,12 +217,57 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
def _button_clicked(self):
|
def _button_clicked(self):
|
||||||
self._stop_countdown()
|
self._stop_countdown()
|
||||||
|
|
||||||
|
def _cb_warninglbl_clicked(self):
|
||||||
|
self._stop_countdown()
|
||||||
|
self.stackedWidget.setCurrentIndex(self.PAGE_CHECKSUMS)
|
||||||
|
|
||||||
def _cb_cmdinfo_clicked(self):
|
def _cb_cmdinfo_clicked(self):
|
||||||
self.stackedWidget.setCurrentIndex(0)
|
self.stackedWidget.setCurrentIndex(self.PAGE_DETAILS)
|
||||||
self._stop_countdown()
|
self._stop_countdown()
|
||||||
|
|
||||||
|
def _cb_update_rule_clicked(self):
|
||||||
|
self.labelChecksumStatus.setStyleSheet('')
|
||||||
|
curRule = self.comboChecksumRule.currentText()
|
||||||
|
if curRule == "":
|
||||||
|
return
|
||||||
|
|
||||||
|
# get rule from the db
|
||||||
|
records = self._rules.get_by_name(self._peer, curRule)
|
||||||
|
if records == None or records.first() == False:
|
||||||
|
self.labelChecksumStatus.setStyleSheet('color: red')
|
||||||
|
self.labelChecksumStatus.setText("✘ " + QC.translate("popups", "Rule not updated, not found by name"))
|
||||||
|
return
|
||||||
|
# transform it to proto rule
|
||||||
|
rule_obj = Rule.new_from_records(records)
|
||||||
|
if rule_obj.operator.type != Config.RULE_TYPE_LIST:
|
||||||
|
if rule_obj.operator.operand == Config.OPERAND_PROCESS_HASH_MD5:
|
||||||
|
rule_obj.operator.data = self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5]
|
||||||
|
else:
|
||||||
|
for op in rule_obj.operator.list:
|
||||||
|
if op.operand == Config.OPERAND_PROCESS_HASH_MD5:
|
||||||
|
op.data = self._con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5]
|
||||||
|
break
|
||||||
|
# add it back again to the db
|
||||||
|
added = self._rules.add_rules(self._peer, [rule_obj])
|
||||||
|
if not added:
|
||||||
|
self.labelChecksumStatus.setStyleSheet('color: red')
|
||||||
|
self.labelChecksumStatus.setText("✘ " + QC.translate("popups", "Rule not updated."))
|
||||||
|
return
|
||||||
|
|
||||||
|
self._nodes.send_notification(
|
||||||
|
self._peer,
|
||||||
|
ui_pb2.Notification(
|
||||||
|
id=int(str(time.time()).replace(".", "")),
|
||||||
|
type=ui_pb2.CHANGE_RULE,
|
||||||
|
data="",
|
||||||
|
rules=[rule_obj]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.labelChecksumStatus.setStyleSheet('color: green')
|
||||||
|
self.labelChecksumStatus.setText("✔" + QC.translate("popups", "Rule updated."))
|
||||||
|
|
||||||
def _cb_cmdback_clicked(self):
|
def _cb_cmdback_clicked(self):
|
||||||
self.stackedWidget.setCurrentIndex(1)
|
self.stackedWidget.setCurrentIndex(self.PAGE_MAIN)
|
||||||
self._stop_countdown()
|
self._stop_countdown()
|
||||||
|
|
||||||
def _set_elide_text(self, widget, text, max_size=132):
|
def _set_elide_text(self, widget, text, max_size=132):
|
||||||
|
@ -235,6 +291,14 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
self._local = is_local
|
self._local = is_local
|
||||||
self._peer = peer
|
self._peer = peer
|
||||||
self._con = connection
|
self._con = connection
|
||||||
|
|
||||||
|
# XXX: workaround for protobufs that don't report the address of
|
||||||
|
# the node. In this case the addr is "unix:/local"
|
||||||
|
proto, addr = self._nodes.get_addr(peer)
|
||||||
|
self._peer = proto
|
||||||
|
if addr != None:
|
||||||
|
self._peer = proto+":"+addr
|
||||||
|
|
||||||
self._done.clear()
|
self._done.clear()
|
||||||
# trigger and show dialog
|
# trigger and show dialog
|
||||||
self._prompt_trigger.emit()
|
self._prompt_trigger.emit()
|
||||||
|
@ -267,12 +331,12 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def on_connection_prompt_triggered(self):
|
def on_connection_prompt_triggered(self):
|
||||||
self.stackedWidget.setCurrentIndex(1)
|
self.stackedWidget.setCurrentIndex(self.PAGE_MAIN)
|
||||||
self._render_connection(self._con)
|
self._render_connection(self._con)
|
||||||
if self._tick > 0:
|
if self._tick > 0:
|
||||||
self.show()
|
self.show()
|
||||||
# render details after displaying the pop-up.
|
# render details after displaying the pop-up.
|
||||||
self._render_details(self._con)
|
self._render_details(self._peer, self.connDetails, self._con)
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def on_tick_triggered(self):
|
def on_tick_triggered(self):
|
||||||
|
@ -344,6 +408,109 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
self.argsLabel.setVisible(False)
|
self.argsLabel.setVisible(False)
|
||||||
self.argsLabel.setText("")
|
self.argsLabel.setText("")
|
||||||
|
|
||||||
|
def _verify_checksums(self, con, rule):
|
||||||
|
"""return true if the checksum of a rule matches the one of the process
|
||||||
|
opening a connection.
|
||||||
|
"""
|
||||||
|
if rule.operator.type != Config.RULE_TYPE_LIST:
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
if con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5] == "":
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
for ro in rule.operator.list:
|
||||||
|
if ro.type == Config.RULE_TYPE_SIMPLE and ro.operand == Config.OPERAND_PROCESS_HASH_MD5:
|
||||||
|
if ro.data != con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5]:
|
||||||
|
return False, ro.data
|
||||||
|
|
||||||
|
return True, ""
|
||||||
|
|
||||||
|
def _display_checksums_warning(self, peer, con):
|
||||||
|
self.messageLabel.setStyleSheet('')
|
||||||
|
self.labelChecksumStatus.setText('')
|
||||||
|
|
||||||
|
records = self._rules.get_by_field(peer, "operator_data", con.process_path)
|
||||||
|
|
||||||
|
if records != None and records.first():
|
||||||
|
rule = Rule.new_from_records(records)
|
||||||
|
validates, expected = self._verify_checksums(con, rule)
|
||||||
|
if not validates:
|
||||||
|
self.messageLabel.setStyleSheet('color: red')
|
||||||
|
self.messageLabel.setText(
|
||||||
|
QC.translate("popups", "WARNING, bad checksum (<a href='#'>More info</a>)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.labelChecksumNote.setText(
|
||||||
|
QC.translate("popups", "<font color=\"red\">WARNING, checksums differ.</font><br><br>Current process ({0}):<br>{1}<br><br>Expected from the rule:<br>{2}"
|
||||||
|
.format(
|
||||||
|
con.process_id,
|
||||||
|
con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5],
|
||||||
|
expected
|
||||||
|
)))
|
||||||
|
|
||||||
|
self.comboChecksumRule.clear()
|
||||||
|
self.comboChecksumRule.addItem(rule.name)
|
||||||
|
while records.next():
|
||||||
|
rule = Rule.new_from_records(records)
|
||||||
|
self.comboChecksumRule.addItem(rule.name)
|
||||||
|
|
||||||
|
return "<b>WARNING</b><br>bad md5<br>This process:{0}<br>Expected from rule: {1}<br><br>".format(
|
||||||
|
con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5],
|
||||||
|
expected
|
||||||
|
)
|
||||||
|
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def _render_details(self, peer, detailsWidget, con):
|
||||||
|
tree = ""
|
||||||
|
space = " "
|
||||||
|
spaces = " "
|
||||||
|
indicator = ""
|
||||||
|
|
||||||
|
self._display_checksums_warning(peer, con)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# reverse() doesn't exist on old protobuf libs.
|
||||||
|
con.process_tree.reverse()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
for path in con.process_tree:
|
||||||
|
tree = "{0}<p>│{1}\t{2}{3}{4}</p>".format(tree, path.value, spaces, indicator, path.key)
|
||||||
|
spaces += " " * 4
|
||||||
|
indicator = "\\_ "
|
||||||
|
|
||||||
|
# XXX: table element doesn't work?
|
||||||
|
details = """<b>{0}</b> {1}:{2} -> {3}:{4}
|
||||||
|
<br><br>
|
||||||
|
<b>Path:</b>{5}{6}<br>
|
||||||
|
<b>Cmdline:</b> {7}<br>
|
||||||
|
<b>CWD:</b>{8}{9}<br>
|
||||||
|
<b>MD5:</b>{10}{11}<br>
|
||||||
|
<b>UID:</b>{12}{13}<br>
|
||||||
|
<b>PID:</b>{14}{15}<br>
|
||||||
|
<br>
|
||||||
|
<b>Process tree:</b><br>
|
||||||
|
{16}
|
||||||
|
<br>
|
||||||
|
<p><b>Environment variables:<b></p>
|
||||||
|
{17}
|
||||||
|
""".format(
|
||||||
|
con.protocol.upper(),
|
||||||
|
con.src_port, con.src_ip, con.dst_ip, con.dst_port,
|
||||||
|
space * 6, con.process_path,
|
||||||
|
" ".join(con.process_args),
|
||||||
|
space * 6, con.process_cwd,
|
||||||
|
space * 7, con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5],
|
||||||
|
space * 9, con.user_id,
|
||||||
|
space * 9, con.process_id,
|
||||||
|
tree,
|
||||||
|
"".join('<p>{}={}</p>'.format(key, value) for key, value in con.process_env.items())
|
||||||
|
)
|
||||||
|
|
||||||
|
detailsWidget.document().clear()
|
||||||
|
detailsWidget.document().setHtml(details)
|
||||||
|
detailsWidget.moveCursor(QtGui.QTextCursor.Start)
|
||||||
|
|
||||||
def _render_connection(self, con):
|
def _render_connection(self, con):
|
||||||
app_name, app_icon, description, _ = self._apps_parser.get_info_by_path(con.process_path, "terminal")
|
app_name, app_icon, description, _ = self._apps_parser.get_info_by_path(con.process_path, "terminal")
|
||||||
app_args = " ".join(con.process_args)
|
app_args = " ".join(con.process_args)
|
||||||
|
@ -357,6 +524,7 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
if app_name == "":
|
if app_name == "":
|
||||||
self.appPathLabel.setVisible(False)
|
self.appPathLabel.setVisible(False)
|
||||||
self.argsLabel.setVisible(False)
|
self.argsLabel.setVisible(False)
|
||||||
|
self.argsLabel.setText("")
|
||||||
app_name = QC.translate("popups", "Unknown process %s" % con.process_path)
|
app_name = QC.translate("popups", "Unknown process %s" % con.process_path)
|
||||||
self.appNameLabel.setText(QC.translate("popups", "Outgoing connection"))
|
self.appNameLabel.setText(QC.translate("popups", "Outgoing connection"))
|
||||||
else:
|
else:
|
||||||
|
@ -454,53 +622,6 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||||
|
|
||||||
self.setFixedSize(self.size())
|
self.setFixedSize(self.size())
|
||||||
|
|
||||||
def _render_details(self, con):
|
|
||||||
tree = ""
|
|
||||||
space = " "
|
|
||||||
spaces = " "
|
|
||||||
indicator = ""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# reverse() doesn't exist on old protobuf libs.
|
|
||||||
con.process_tree.reverse()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
for path in con.process_tree:
|
|
||||||
tree = "{0}<p>│{1}\t{2}{3}{4}</p>".format(tree, path.value, spaces, indicator, path.key)
|
|
||||||
spaces += " " * 4
|
|
||||||
indicator = "\_ "
|
|
||||||
|
|
||||||
# XXX: table element doesn't work?
|
|
||||||
details = """<b>{0}</b> {1}:{2} -> {3}:{4}
|
|
||||||
<br><br>
|
|
||||||
<b>Path:</b>{5}{6}<br>
|
|
||||||
<b>Cmdline:</b> {7}<br>
|
|
||||||
<b>CWD:</b>{8}{9}<br>
|
|
||||||
<b>MD5:</b>{10}{11}<br>
|
|
||||||
<b>UID:</b>{12}{13}<br>
|
|
||||||
<b>PID:</b>{14}{15}<br>
|
|
||||||
<br>
|
|
||||||
<b>Process tree:</b><br>
|
|
||||||
{16}
|
|
||||||
<br>
|
|
||||||
<p><b>Environment variables:<b></p>
|
|
||||||
{17}
|
|
||||||
""".format(
|
|
||||||
con.protocol.upper(),
|
|
||||||
con.src_port, con.src_ip, con.dst_ip, con.dst_port,
|
|
||||||
space * 6, con.process_path,
|
|
||||||
" ".join(con.process_args),
|
|
||||||
space * 6, con.process_cwd,
|
|
||||||
space * 7, con.process_checksums[Config.OPERAND_PROCESS_HASH_MD5],
|
|
||||||
space * 9, con.user_id,
|
|
||||||
space * 9, con.process_id,
|
|
||||||
tree,
|
|
||||||
"".join('<p>{}={}</p>'.format(key, value) for key, value in con.process_env.items())
|
|
||||||
)
|
|
||||||
|
|
||||||
self.connDetails.document().clear()
|
|
||||||
self.connDetails.document().setHtml(details)
|
|
||||||
self.connDetails.moveCursor(QtGui.QTextCursor.Start)
|
|
||||||
|
|
||||||
# https://gis.stackexchange.com/questions/86398/how-to-disable-the-escape-key-for-a-dialog
|
# https://gis.stackexchange.com/questions/86398/how-to-disable-the-escape-key-for-a-dialog
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>563</width>
|
<width>563</width>
|
||||||
<height>323</height>
|
<height>339</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -188,7 +188,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="emblem-important">
|
<iconset theme="emblem-important">
|
||||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
<normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="popupMode">
|
<property name="popupMode">
|
||||||
<enum>QToolButton::MenuButtonPopup</enum>
|
<enum>QToolButton::MenuButtonPopup</enum>
|
||||||
|
@ -223,7 +223,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="emblem-default">
|
<iconset theme="emblem-default">
|
||||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
<normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -263,7 +263,7 @@
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page">
|
<widget class="QWidget" name="page">
|
||||||
<layout class="QGridLayout" name="gridLayout_5">
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
|
@ -297,7 +297,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="go-previous">
|
<iconset theme="go-previous">
|
||||||
<normaloff>.</normaloff>.</iconset>
|
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="flat">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -328,8 +328,105 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_3">
|
||||||
|
<layout class="QGridLayout" name="gridLayout_6">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="cmdBackChecksums">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="go-previous">
|
||||||
|
<normaloff>../../../../../../.designer/backup</normaloff>../../../../../../.designer/backup</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QPushButton" name="cmdUpdateRule">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Update rule</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="reload">
|
||||||
|
<normaloff>../../../../../../.designer/backup</normaloff>../../../../../../.designer/backup</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="labelChecksumNote">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QComboBox" name="comboChecksumRule"/>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="labelChecksumStatus">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="page_2">
|
<widget class="QWidget" name="page_2">
|
||||||
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0,1">
|
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0,0,0">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -345,6 +442,44 @@
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="messageLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Chromium Web Browser wants to connect to www.evilsocket.net on tcp port 443. And maybe to www.goodsocket.net on port 344</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="margin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="Line" name="line_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
|
@ -412,6 +547,26 @@
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QPushButton" name="cmdInfo">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset theme="dialog-information">
|
||||||
|
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="appNameLabel">
|
<widget class="QLabel" name="appNameLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -445,24 +600,35 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="3" column="0" colspan="2">
|
||||||
<widget class="QPushButton" name="cmdInfo">
|
<widget class="QLabel" name="argsLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>10</pointsize>
|
||||||
|
<kerning>true</kerning>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string notr="true">chromium -arg1 -arg2</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="textFormat">
|
||||||
<iconset theme="dialog-information">
|
<enum>Qt::PlainText</enum>
|
||||||
<normaloff>.</normaloff>.</iconset>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="flat">
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
|
@ -506,38 +672,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">(/path/to/bin/chromium)</string>
|
<string notr="true">(/absolute/path/to/bin/chromium)</string>
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::PlainText</enum>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="2">
|
|
||||||
<widget class="QLabel" name="argsLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<pointsize>10</pointsize>
|
|
||||||
<kerning>true</kerning>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">(/path/to/bin/chromium)</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="textFormat">
|
<property name="textFormat">
|
||||||
<enum>Qt::PlainText</enum>
|
<enum>Qt::PlainText</enum>
|
||||||
|
@ -557,20 +692,7 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="Line" name="line_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
|
@ -946,31 +1068,6 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="messageLabel">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">Chromium Web Browser wants to connect to www.evilsocket.net on tcp port 443. And maybe to www.goodsocket.net on port 344</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="margin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -132,6 +132,12 @@ class Rules(QObject):
|
||||||
def delete_by_field(self, field, values):
|
def delete_by_field(self, field, values):
|
||||||
return self._db.delete_rules_by_field(field, values)
|
return self._db.delete_rules_by_field(field, values)
|
||||||
|
|
||||||
|
def get_by_name(self, node, name):
|
||||||
|
return self._db.get_rule(name, node)
|
||||||
|
|
||||||
|
def get_by_field(self, node, field, value):
|
||||||
|
return self._db.get_rule_by_field(node, field, value)
|
||||||
|
|
||||||
def exists(self, rule, node_addr):
|
def exists(self, rule, node_addr):
|
||||||
return self._db.rule_exists(rule, node_addr)
|
return self._db.rule_exists(rule, node_addr)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue