mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
added support for list of domains
Initial support to filter connections using lists of domains. The lists must be in hosts format: - 0.0.0.0 www.domain.com - 127.0.0.1 www.domain.com From the rules editor, create a new rule, and select [x] To this lists of domains Select a directory with files in hosts format, select [x] Priority rule, select [x] Deny and click on Apply. An example of a list in hosts format: https://www.github.developerdan.com/hosts/lists/ads-and-tracking-extended.txt Note: you can also add a list of domains to allow, not only domains to block. TODOs: - support for URLs besides directories (local lists). - support for scheduled updates of the above URLs. related #298
This commit is contained in:
parent
fab5d97cd8
commit
26671ded24
6 changed files with 325 additions and 195 deletions
|
@ -93,7 +93,9 @@ func (l *Loader) Load(path string) error {
|
|||
r.Operator.Compile()
|
||||
if r.Operator.Type == List {
|
||||
for i := 0; i < len(r.Operator.List); i++ {
|
||||
r.Operator.List[i].Compile()
|
||||
if err := r.Operator.List[i].Compile(); err != nil {
|
||||
log.Warning("Operator.Compile() error: %s: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
diskRules[r.Name] = r.Name
|
||||
|
@ -211,14 +213,24 @@ func (l *Loader) replaceUserRule(rule *Rule) (err error) {
|
|||
l.rules[rule.Name] = rule
|
||||
l.sortRules()
|
||||
l.Unlock()
|
||||
|
||||
rule.Operator.isCompiled = false
|
||||
if err := rule.Operator.Compile(); err != nil {
|
||||
log.Warning("Operator.Compile() error: %s: ", err, rule.Operator.Data)
|
||||
}
|
||||
|
||||
if rule.Operator.Type == List {
|
||||
// TODO: use List protobuf object instead of un/marshalling to/from json
|
||||
if err = json.Unmarshal([]byte(rule.Operator.Data), &rule.Operator.List); err != nil {
|
||||
return fmt.Errorf("Error loading rule of type list: %s", err)
|
||||
}
|
||||
|
||||
// force re-Compile() changed rule
|
||||
for i := 0; i < len(rule.Operator.List); i++ {
|
||||
rule.Operator.List[i].isCompiled = false
|
||||
rule.Operator.List[i].Compile()
|
||||
if err := rule.Operator.Compile(); err != nil {
|
||||
log.Warning("Operator.Compile() error: %s: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ const (
|
|||
Complex = Type("complex") // for future use
|
||||
List = Type("list")
|
||||
Network = Type("network")
|
||||
Lists = Type("lists")
|
||||
)
|
||||
|
||||
// Available operands
|
||||
|
@ -46,6 +47,7 @@ const (
|
|||
OpDstNetwork = Operand("dest.network")
|
||||
OpProto = Operand("protocol")
|
||||
OpList = Operand("list")
|
||||
OpDomainsLists = Operand("lists.domains")
|
||||
)
|
||||
|
||||
type opCallback func(value interface{}) bool
|
||||
|
@ -62,6 +64,7 @@ type Operator struct {
|
|||
re *regexp.Regexp
|
||||
netMask *net.IPNet
|
||||
isCompiled bool
|
||||
lists map[string]string
|
||||
}
|
||||
|
||||
// NewOperator returns a new operator object
|
||||
|
@ -97,6 +100,14 @@ func (o *Operator) Compile() error {
|
|||
return err
|
||||
}
|
||||
o.re = re
|
||||
} else if o.Type == Lists && o.Operand == OpDomainsLists {
|
||||
if o.Data == "" {
|
||||
return fmt.Errorf("Operand lists is empty, nothing to load: %s", o)
|
||||
}
|
||||
if err := o.loadLists(); err != nil {
|
||||
return err
|
||||
}
|
||||
o.cb = o.domainsListCmp
|
||||
} else if o.Type == List {
|
||||
o.Operand = OpList
|
||||
} else if o.Type == Network {
|
||||
|
@ -148,6 +159,18 @@ func (o *Operator) cmpNetwork(destIP interface{}) bool {
|
|||
return o.netMask.Contains(destIP.(net.IP))
|
||||
}
|
||||
|
||||
func (o *Operator) domainsListCmp(v interface{}) bool {
|
||||
dstHost := v.(string)
|
||||
if dstHost == "" {
|
||||
return false
|
||||
}
|
||||
if _, found := o.lists[dstHost]; found {
|
||||
log.Debug("%s: %s, %s", log.Red("domain list match"), dstHost, o.lists[dstHost])
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Operator) listMatch(con interface{}) bool {
|
||||
res := true
|
||||
for i := 0; i < len(o.List); i++ {
|
||||
|
@ -188,6 +211,8 @@ func (o *Operator) Match(con *conman.Connection) bool {
|
|||
return o.cb(con.DstIP)
|
||||
} else if o.Operand == OpList {
|
||||
return o.listMatch(con)
|
||||
} else if o.Operand == OpDomainsLists {
|
||||
return o.cb(con.DstHost)
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
|
@ -7,7 +7,7 @@ class Config:
|
|||
|
||||
HELP_URL = "https://github.com/gustavo-iniguez-goya/opensnitch/wiki/Configurations"
|
||||
|
||||
RulesTypes = ("list", "simple", "regexp", "network")
|
||||
RulesTypes = ("list", "lists", "simple", "regexp", "network")
|
||||
|
||||
DEFAULT_DURATION_IDX = 6 # until restart
|
||||
DEFAULT_TARGET_PROCESS = 0
|
||||
|
|
|
@ -15,7 +15,7 @@ from config import Config
|
|||
from nodes import Nodes
|
||||
from database import Database
|
||||
from version import version
|
||||
from utils import Message
|
||||
from utils import Message, FileDialog
|
||||
|
||||
DIALOG_UI_PATH = "%s/../res/ruleseditor.ui" % os.path.dirname(sys.modules[__name__].__file__)
|
||||
class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
||||
|
@ -46,6 +46,7 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
self.buttonBox.button(QtWidgets.QDialogButtonBox.Close).clicked.connect(self._cb_close_clicked)
|
||||
self.buttonBox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(self._cb_apply_clicked)
|
||||
self.buttonBox.button(QtWidgets.QDialogButtonBox.Help).clicked.connect(self._cb_help_clicked)
|
||||
self.selectListButton.clicked.connect(self._cb_select_list_button_clicked)
|
||||
self.protoCheck.toggled.connect(self._cb_proto_check_toggled)
|
||||
self.procCheck.toggled.connect(self._cb_proc_check_toggled)
|
||||
self.cmdlineCheck.toggled.connect(self._cb_cmdline_check_toggled)
|
||||
|
@ -53,6 +54,7 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
self.uidCheck.toggled.connect(self._cb_uid_check_toggled)
|
||||
self.dstIPCheck.toggled.connect(self._cb_dstip_check_toggled)
|
||||
self.dstHostCheck.toggled.connect(self._cb_dsthost_check_toggled)
|
||||
self.dstListsCheck.toggled.connect(self._cb_dstlists_check_toggled)
|
||||
|
||||
if QtGui.QIcon.hasThemeIcon("emblem-default") == False:
|
||||
self.actionAllowRadio.setIcon(self.style().standardIcon(getattr(QtWidgets.QStyle, "SP_DialogApplyButton")))
|
||||
|
@ -76,6 +78,11 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
def _cb_help_clicked(self):
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl(Config.HELP_URL))
|
||||
|
||||
def _cb_select_list_button_clicked(self):
|
||||
dirName = FileDialog.select_dir(self, self.dstListsLine.text())
|
||||
if dirName != None and dirName != "":
|
||||
self.dstListsLine.setText(dirName)
|
||||
|
||||
def _cb_proto_check_toggled(self, state):
|
||||
self.protoCombo.setEnabled(state)
|
||||
|
||||
|
@ -97,6 +104,10 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
def _cb_dsthost_check_toggled(self, state):
|
||||
self.dstHostLine.setEnabled(state)
|
||||
|
||||
def _cb_dstlists_check_toggled(self, state):
|
||||
self.dstListsLine.setEnabled(state)
|
||||
self.selectListButton.setEnabled(state)
|
||||
|
||||
def _set_status_error(self, msg):
|
||||
self.statusLabel.setStyleSheet('color: red')
|
||||
self.statusLabel.setText(msg)
|
||||
|
@ -184,6 +195,10 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
self.dstHostCheck.setChecked(False)
|
||||
self.dstHostLine.setText("")
|
||||
|
||||
self.selectListButton.setEnabled(False)
|
||||
self.dstListsCheck.setChecked(False)
|
||||
self.dstListsLine.setText("")
|
||||
|
||||
def _load_rule(self, addr=None, rule=None):
|
||||
self._load_nodes(addr)
|
||||
|
||||
|
@ -255,6 +270,12 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
self.dstHostLine.setEnabled(True)
|
||||
self.dstHostLine.setText(operator.data)
|
||||
|
||||
if operator.operand == "lists.domains":
|
||||
self.dstListsCheck.setChecked(True)
|
||||
self.dstListsCheck.setEnabled(True)
|
||||
self.dstListsLine.setText(operator.data)
|
||||
self.selectListButton.setEnabled(True)
|
||||
|
||||
def _load_nodes(self, addr=None):
|
||||
try:
|
||||
self.nodesCombo.clear()
|
||||
|
@ -332,7 +353,7 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
Ensure that some constraints are met:
|
||||
- Determine if a field can be a regexp.
|
||||
- Validate regexp.
|
||||
- Fields cam not be empty.
|
||||
- Fields cannot be empty.
|
||||
- If the user has not provided a rule name, auto assign one.
|
||||
"""
|
||||
self.rule = ui_pb2.Rule()
|
||||
|
@ -497,11 +518,29 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
|
|||
if self._is_valid_regex(self.uidLine.text()) == False:
|
||||
return False, QC.translate("rules", "User ID regexp error")
|
||||
|
||||
if self.dstListsCheck.isChecked():
|
||||
if self.dstListsLine.text() == "":
|
||||
return False, QC.translate("rules", "Lists field cannot be empty")
|
||||
if os.path.isdir(self.dstListsLine.text()) == False:
|
||||
return False, QC.translate("rules", "Lists field must be a directory")
|
||||
|
||||
self.rule.operator.type = "lists"
|
||||
self.rule.operator.operand = "lists.domains"
|
||||
rule_data.append(
|
||||
{
|
||||
'type': 'lists',
|
||||
'operand': 'lists.domains',
|
||||
'data': self.dstListsLine.text(),
|
||||
'sensitive': self.sensitiveCheck.isChecked()
|
||||
})
|
||||
self.rule.operator.data = json.dumps(rule_data)
|
||||
|
||||
|
||||
if len(rule_data) > 1:
|
||||
self.rule.operator.type = "list"
|
||||
self.rule.operator.operand = ""
|
||||
self.rule.operator.data = json.dumps(rule_data)
|
||||
elif len(rule_data) == 1:
|
||||
else:
|
||||
self.rule.operator.operand = rule_data[0]['operand']
|
||||
self.rule.operator.data = rule_data[0]['data']
|
||||
if self._is_regex(self.rule.operator.data):
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>651</width>
|
||||
<height>526</height>
|
||||
<height>543</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -96,7 +96,7 @@
|
|||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0">
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0,0">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
|
@ -109,22 +109,15 @@
|
|||
<property name="verticalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="cmdlineCheck">
|
||||
<item row="11" column="1">
|
||||
<widget class="QCheckBox" name="dstIPCheck">
|
||||
<property name="text">
|
||||
<string>From this command line</string>
|
||||
<string>To this IP / Network</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="procCheck">
|
||||
<property name="text">
|
||||
<string>From this executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<item row="10" column="4" colspan="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -136,8 +129,18 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<item row="6" column="4" colspan="3">
|
||||
<widget class="QLineEdit" name="procLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>/path/to/executable, .*/bin/executable[0-9\.]+$, ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="4" colspan="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -156,87 +159,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3" colspan="3">
|
||||
<widget class="QLineEdit" name="procLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>/path/to/executable, .*/bin/executable[0-9\.]+$, ...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3" colspan="2">
|
||||
<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>
|
||||
<item row="11" column="1">
|
||||
<widget class="QCheckBox" name="dstIPCheck">
|
||||
<property name="text">
|
||||
<string>To this IP / Network</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="5">
|
||||
<widget class="QLineEdit" name="uidLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="5">
|
||||
<widget class="QComboBox" name="durationCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>once</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>30s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5m</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>15m</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>30m</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1h</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>until reboot</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>always</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="dstPortCheck">
|
||||
<property name="text">
|
||||
|
@ -244,36 +166,15 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="uidCheck">
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="dstListsCheck">
|
||||
<property name="text">
|
||||
<string>From this user ID</string>
|
||||
<string>To this list of domains</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="3" colspan="3">
|
||||
<widget class="QLineEdit" name="dstHostLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Commas or spaces are not allowed to specify multiple domains.
|
||||
|
||||
Use regular expressions instead:
|
||||
.*(opensnitch|duckduckgo).com
|
||||
.*\.google.com
|
||||
|
||||
or a single domain:
|
||||
www.gnu.org - it'll only match www.gnu.org, nor ftp.gnu.org, nor www2.gnu.org, ...
|
||||
gnu.org - it'll only match gnu.org, nor www.gnu.org, nor ftp.gnu.org, ...</string>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>www.domain.org, .*\.domain.org</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="3" colspan="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<item row="4" column="4">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
|
@ -285,53 +186,7 @@ gnu.org - it'll only match gnu.org, nor www.gnu.org, nor ftp.gnu.org, ..
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="5">
|
||||
<widget class="QComboBox" name="protoCombo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Only TCP, UDP or UDPLITE are allowed</p><p>You can use regexp, i.e.: ^(TCP|UDP)$</p></body></html></string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string>TCP</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TCP</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDP</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDPLITE</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TCP6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDP6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDPLITE6</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="3" colspan="3">
|
||||
<item row="11" column="4" colspan="3">
|
||||
<widget class="QComboBox" name="dstIPCombo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
|
@ -426,17 +281,98 @@ Note: Commas or spaces are not allowed to separate IPs or networks.</string>
|
|||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Duration</string>
|
||||
<item row="3" column="4">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="10" column="6">
|
||||
<widget class="QLineEdit" name="uidLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="protoCheck">
|
||||
<property name="text">
|
||||
<string>Protocol</string>
|
||||
<item row="8" column="6">
|
||||
<widget class="QLineEdit" name="dstPortLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>You can specify multiple ports using regular expressions:</p><p><br/></p><p>- 53, 80 or 443:</p><p>^(53|80|443)$</p><p><br/></p><p>- 53, 443 or 5551, 5552, 5553, etc:</p><p>^(53|443|555[0-9])$</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="6">
|
||||
<widget class="QComboBox" name="durationCombo">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>once</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>30s</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5m</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>15m</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>30m</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1h</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>until reboot</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>always</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="4" colspan="3">
|
||||
<widget class="QLineEdit" name="dstHostLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Commas or spaces are not allowed to specify multiple domains.
|
||||
|
||||
Use regular expressions instead:
|
||||
.*(opensnitch|duckduckgo).com
|
||||
.*\.google.com
|
||||
|
||||
or a single domain:
|
||||
www.gnu.org - it'll only match www.gnu.org, nor ftp.gnu.org, nor www2.gnu.org, ...
|
||||
gnu.org - it'll only match gnu.org, nor www.gnu.org, nor ftp.gnu.org, ...</string>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>www.domain.org, .*\.domain.org</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -447,14 +383,81 @@ Note: Commas or spaces are not allowed to separate IPs or networks.</string>
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3" colspan="3">
|
||||
<item row="7" column="4" colspan="3">
|
||||
<widget class="QLineEdit" name="cmdlineLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Duration</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="6">
|
||||
<widget class="QComboBox" name="protoCombo">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Only TCP, UDP or UDPLITE are allowed</p><p>You can use regexp, i.e.: ^(TCP|UDP)$</p></body></html></string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentText">
|
||||
<string>TCP</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TCP</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDP</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDPLITE</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TCP6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDP6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>UDPLITE6</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="protoCheck">
|
||||
<property name="text">
|
||||
<string>Protocol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="procCheck">
|
||||
<property name="text">
|
||||
<string>From this executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="6">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="actionDenyRadio">
|
||||
|
@ -498,16 +501,47 @@ Note: Commas or spaces are not allowed to separate IPs or networks.</string>
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="5">
|
||||
<widget class="QLineEdit" name="dstPortLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>You can specify multiple ports using regular expressions:</p><p><br/></p><p>- 53, 80 or 443:</p><p>^(53|80|443)$</p><p><br/></p><p>- 53, 443 or 5551, 5552, 5553, etc:</p><p>^(53|443|555[0-9])$</p></body></html></string>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="cmdlineCheck">
|
||||
<property name="text">
|
||||
<string>From this command line</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="uidCheck">
|
||||
<property name="text">
|
||||
<string>From this user ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="4" colspan="3">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectListButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="search"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="dstListsLine">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select a directory with lists of domains to block or allow.</p><p>Put inside that directory files with any extension containing lists of domains.</p><p><br/>The format of each entry of a list is as follow (hosts format):</p><p>127.0.0.1 www.domain.com</p><p>or </p><p>0.0.0.0 www.domain.com</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -6,9 +6,8 @@ class Message():
|
|||
@staticmethod
|
||||
def ok(title, message, icon):
|
||||
msgBox = QtWidgets.QMessageBox()
|
||||
msgBox.setText(title)
|
||||
msgBox.setText("<b>{0}</b><br><br>{1}".format(title, message))
|
||||
msgBox.setIcon(icon)
|
||||
msgBox.setInformativeText(message)
|
||||
msgBox.setStandardButtons(QtWidgets.QMessageBox.Ok)
|
||||
msgBox.exec_()
|
||||
|
||||
|
@ -21,3 +20,24 @@ class Message():
|
|||
msgBox.setStandardButtons(QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.Yes)
|
||||
msgBox.setDefaultButton(QtWidgets.QMessageBox.Cancel)
|
||||
return msgBox.exec_()
|
||||
|
||||
class FileDialog():
|
||||
|
||||
@staticmethod
|
||||
def save(parent):
|
||||
options = QtWidgets.QFileDialog.Options()
|
||||
fileName, _ = QtWidgets.QFileDialog.getSaveFileName(parent, "", "","All Files (*)", options=options)
|
||||
return fileName
|
||||
|
||||
@staticmethod
|
||||
def select(parent):
|
||||
options = QtWidgets.QFileDialog.Options()
|
||||
fileName, _ = QtWidgets.QFileDialog.getOpenFileName(parent, "", "","All Files (*)", options=options)
|
||||
return fileName
|
||||
|
||||
@staticmethod
|
||||
def select_dir(parent, current_dir):
|
||||
options = QtWidgets.QFileDialog.Options()
|
||||
fileName = QtWidgets.QFileDialog.getExistingDirectory(parent, "", current_dir, options)
|
||||
return fileName
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue