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
|
||||
|
||||
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):
|
||||
"""
|
||||
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.actions import Actions
|
||||
from opensnitch.rules import Rules, Rule
|
||||
from opensnitch.nodes import Nodes
|
||||
|
||||
from opensnitch import ui_pb2
|
||||
|
||||
|
@ -28,6 +29,10 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
_tick_trigger = QtCore.pyqtSignal()
|
||||
_timeout_trigger = QtCore.pyqtSignal()
|
||||
|
||||
PAGE_MAIN = 2
|
||||
PAGE_DETAILS = 0
|
||||
PAGE_CHECKSUMS = 1
|
||||
|
||||
DEFAULT_TIMEOUT = 15
|
||||
|
||||
# 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
|
||||
self._cfg = Config.get()
|
||||
self._rules = Rules.instance()
|
||||
self._nodes = Nodes.instance()
|
||||
|
||||
self.setupUi(self)
|
||||
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.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")
|
||||
denyIcon = Icons.new(self, "emblem-important")
|
||||
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.cmdBack.setIcon(backIcon)
|
||||
self.cmdBackChecksums.setIcon(backIcon)
|
||||
|
||||
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.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.stackedWidget.setCurrentIndex(1)
|
||||
self.stackedWidget.setCurrentIndex(self.PAGE_MAIN)
|
||||
|
||||
self._ischeckAdvanceded = state
|
||||
self.adjust_size()
|
||||
|
@ -206,12 +217,57 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
def _button_clicked(self):
|
||||
self._stop_countdown()
|
||||
|
||||
def _cb_warninglbl_clicked(self):
|
||||
self._stop_countdown()
|
||||
self.stackedWidget.setCurrentIndex(self.PAGE_CHECKSUMS)
|
||||
|
||||
def _cb_cmdinfo_clicked(self):
|
||||
self.stackedWidget.setCurrentIndex(0)
|
||||
self.stackedWidget.setCurrentIndex(self.PAGE_DETAILS)
|
||||
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):
|
||||
self.stackedWidget.setCurrentIndex(1)
|
||||
self.stackedWidget.setCurrentIndex(self.PAGE_MAIN)
|
||||
self._stop_countdown()
|
||||
|
||||
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._peer = peer
|
||||
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()
|
||||
# trigger and show dialog
|
||||
self._prompt_trigger.emit()
|
||||
|
@ -267,12 +331,12 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
|
||||
@QtCore.pyqtSlot()
|
||||
def on_connection_prompt_triggered(self):
|
||||
self.stackedWidget.setCurrentIndex(1)
|
||||
self.stackedWidget.setCurrentIndex(self.PAGE_MAIN)
|
||||
self._render_connection(self._con)
|
||||
if self._tick > 0:
|
||||
self.show()
|
||||
# render details after displaying the pop-up.
|
||||
self._render_details(self._con)
|
||||
self._render_details(self._peer, self.connDetails, self._con)
|
||||
|
||||
@QtCore.pyqtSlot()
|
||||
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.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):
|
||||
app_name, app_icon, description, _ = self._apps_parser.get_info_by_path(con.process_path, "terminal")
|
||||
app_args = " ".join(con.process_args)
|
||||
|
@ -357,6 +524,7 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
if app_name == "":
|
||||
self.appPathLabel.setVisible(False)
|
||||
self.argsLabel.setVisible(False)
|
||||
self.argsLabel.setText("")
|
||||
app_name = QC.translate("popups", "Unknown process %s" % con.process_path)
|
||||
self.appNameLabel.setText(QC.translate("popups", "Outgoing connection"))
|
||||
else:
|
||||
|
@ -454,53 +622,6 @@ class PromptDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
|
||||
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
|
||||
def keyPressEvent(self, event):
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>563</width>
|
||||
<height>323</height>
|
||||
<height>339</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
@ -188,7 +188,7 @@
|
|||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="emblem-important">
|
||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||
<normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::MenuButtonPopup</enum>
|
||||
|
@ -223,7 +223,7 @@
|
|||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="emblem-default">
|
||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||
<normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../../../../../../../../../.designer/backup</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -263,7 +263,7 @@
|
|||
<item row="0" column="0">
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
|
@ -297,7 +297,7 @@
|
|||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="go-previous">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
<normaloff>../../../../../../../../../../.designer/backup</normaloff>../../../../../../../../../../.designer/backup</iconset>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
|
@ -328,8 +328,105 @@
|
|||
</item>
|
||||
</layout>
|
||||
</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">
|
||||
<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">
|
||||
<number>2</number>
|
||||
</property>
|
||||
|
@ -345,6 +442,44 @@
|
|||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</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">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="bottomMargin">
|
||||
|
@ -412,6 +547,26 @@
|
|||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</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">
|
||||
<widget class="QLabel" name="appNameLabel">
|
||||
<property name="sizePolicy">
|
||||
|
@ -445,24 +600,35 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="cmdInfo">
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="argsLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<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/>
|
||||
<string notr="true">chromium -arg1 -arg2</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="dialog-information">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<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="1" column="0" colspan="2">
|
||||
|
@ -506,38 +672,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">(/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>
|
||||
<string notr="true">(/absolute/path/to/bin/chromium)</string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::PlainText</enum>
|
||||
|
@ -557,20 +692,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</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="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
|
@ -946,31 +1068,6 @@
|
|||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
|
@ -132,6 +132,12 @@ class Rules(QObject):
|
|||
def delete_by_field(self, 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):
|
||||
return self._db.rule_exists(rule, node_addr)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue