def _send_rule(self): self._cfg.setSettings("promptDialog/geometry", self.saveGeometry()) self._rule = ui_pb2.Rule(name="user.choice") self._rule.enabled = True self._rule.action = Config.ACTION_DENY if self._default_action == self.ACTION_IDX_DENY else Config.ACTION_ALLOW self._rule.duration = self._get_duration( self.durationCombo.currentIndex()) what_idx = self.whatCombo.currentIndex() self._rule.operator.type, self._rule.operator.operand, self._rule.operator.data = self._get_combo_operator( self.whatCombo, what_idx) if self._rule.operator.data == "": print("Invalid rule, discarding: ", self._rule) self._rule = None self._done.set() return rule_temp_name = self._get_rule_name(self._rule) self._rule.name = rule_temp_name # TODO: move to a method data = [] if self._ischeckAdvanceded and self.checkDstIP.isChecked( ) and self.whatCombo.itemData(what_idx) != self.FIELD_DST_IP: _type, _operand, _data = self._get_combo_operator( self.whatIPCombo, self.whatIPCombo.currentIndex()) data.append({"type": _type, "operand": _operand, "data": _data}) rule_temp_name = slugify("%s %s" % (rule_temp_name, _data)) if self._ischeckAdvanceded and self.checkDstPort.isChecked( ) and self.whatCombo.itemData(what_idx) != self.FIELD_DST_PORT: data.append({ "type": "simple", "operand": "dest.port", "data": str(self._con.dst_port) }) rule_temp_name = slugify("%s %s" % (rule_temp_name, str(self._con.dst_port))) if self._ischeckAdvanceded and self.checkUserID.isChecked( ) and self.whatCombo.itemData(what_idx) != self.FIELD_USER_ID: data.append({ "type": "simple", "operand": "user.id", "data": str(self._con.user_id) }) rule_temp_name = slugify("%s %s" % (rule_temp_name, str(self._con.user_id))) if self._ischeckAdvanceded: data.append({ "type": self._rule.operator.type, "operand": self._rule.operator.operand, "data": self._rule.operator.data }) self._rule.operator.data = json.dumps(data) self._rule.operator.type = "list" self._rule.operator.operand = "" self._rule.name = rule_temp_name self.hide() if self._ischeckAdvanceded: self.checkAdvanced.toggle() self._ischeckAdvanceded = False # signal that the user took a decision and # a new rule is available self._done.set()
def _save_rule(self): """ Create a new rule based on the fields selected. Ensure that some constraints are met: - Determine if a field can be a regexp. - Validate regexp. - Fields cam not be empty. - If the user has not provided a rule name, auto assign one. """ self.rule = ui_pb2.Rule() self.rule.name = self.ruleNameEdit.text() self.rule.enabled = self.enableCheck.isChecked() self.rule.precedence = self.precedenceCheck.isChecked() self.rule.action = Config.ACTION_DENY if self.actionDenyRadio.isChecked( ) else Config.ACTION_ALLOW self.rule.operator.type = "simple" # TODO: move to config.get_duration() if self.durationCombo.currentIndex() == 0: self.rule.duration = Config.DURATION_ONCE elif self.durationCombo.currentIndex() == 6: self.rule.duration = Config.DURATION_UNTIL_RESTART elif self.durationCombo.currentIndex() == 7: self.rule.duration = Config.DURATION_ALWAYS else: self.rule.duration = self.durationCombo.currentText() # FIXME: there should be a sensitive checkbox per operand self.rule.operator.sensitive = self.sensitiveCheck.isChecked() rule_data = [] if self.protoCheck.isChecked(): if self.protoCombo.currentText() == "": return False, QtCore.QCoreApplication.translate( "rules", "protocol can not be empty, or uncheck it") self.rule.operator.operand = "protocol" self.rule.operator.data = self.protoCombo.currentText() rule_data.append({ "type": "simple", "operand": "protocol", "data": self.protoCombo.currentText().lower(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.protoCombo.currentText()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex( self.protoCombo.currentText()) == False: return False, QtCore.QCoreApplication.translate( "rules", "Protocol regexp error") if self.procCheck.isChecked(): if self.procLine.text() == "": return False, QtCore.QCoreApplication.translate( "rules", "process path can not be empty") self.rule.operator.operand = "process.path" self.rule.operator.data = self.procLine.text() rule_data.append({ "type": "simple", "operand": "process.path", "data": self.procLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.procLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.procLine.text()) == False: return False, QtCore.QCoreApplication.translate( "rules", "Process path regexp error") if self.cmdlineCheck.isChecked(): if self.cmdlineLine.text() == "": return False, QtCore.QCoreApplication.translate( "rules", "command line can not be empty") self.rule.operator.operand = "process.command" self.rule.operator.data = self.cmdlineLine.text() rule_data.append({ 'type': 'simple', 'operand': 'process.command', 'data': self.cmdlineLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.cmdlineLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.cmdlineLine.text()) == False: return False, QtCore.QCoreApplication.translate( "rules", "Command line regexp error") if self.dstPortCheck.isChecked(): if self.dstPortLine.text() == "": return False, QtCore.QCoreApplication.translate( "rules", "Dest port can not be empty") self.rule.operator.operand = "dest.port" self.rule.operator.data = self.dstPortLine.text() rule_data.append({ 'type': 'simple', 'operand': 'dest.port', 'data': self.dstPortLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.dstPortLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.dstPortLine.text()) == False: return False, QtCore.QCoreApplication.translate( "rules", "Dst port regexp error") if self.dstHostCheck.isChecked(): if self.dstHostLine.text() == "": return False, QtCore.QCoreApplication.translate( "rules", "Dest host can not be empty") self.rule.operator.operand = "dest.host" self.rule.operator.data = self.dstHostLine.text() rule_data.append({ 'type': 'simple', 'operand': 'dest.host', 'data': self.dstHostLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.dstHostLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.dstHostLine.text()) == False: return False, QtCore.QCoreApplication.translate( "rules", "Dst host regexp error") if self.dstIPCheck.isChecked(): if self.dstIPCombo.currentText() == "": return False, QtCore.QCoreApplication.translate( "rules", "Dest IP/Network can not be empty") dstIPtext = self.dstIPCombo.currentText() if dstIPtext == self.LAN_LABEL: self.rule.operator.operand = "dest.ip" self.rule.operator.type = "regexp" dstIPtext = self.LAN_RANGES else: try: if type(ipaddress.ip_address(self.dstIPCombo.currentText())) == ipaddress.IPv4Address \ or type(ipaddress.ip_address(self.dstIPCombo.currentText())) == ipaddress.IPv6Address: self.rule.operator.operand = "dest.ip" self.rule.operator.type = "simple" except Exception: self.rule.operator.operand = "dest.network" self.rule.operator.type = "network" if self._is_regex(dstIPtext): self.rule.operator.type = "regexp" if self._is_valid_regex( self.dstIPCombo.currentText()) == False: return False, QtCore.QCoreApplication.translate( "rules", "Dst IP regexp error") rule_data.append({ 'type': self.rule.operator.type, 'operand': self.rule.operator.operand, 'data': dstIPtext, "sensitive": self.sensitiveCheck.isChecked() }) if self.uidCheck.isChecked(): if self.uidLine.text() == "": return False, QtCore.QCoreApplication.translate( "rules", "User ID can not be empty") self.rule.operator.operand = "user.id" self.rule.operator.data = self.uidLine.text() rule_data.append({ 'type': 'simple', 'operand': 'user.id', 'data': self.uidLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.uidLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.uidLine.text()) == False: return False, QtCore.QCoreApplication.translate( "rules", "User ID regexp error") 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: self.rule.operator.operand = rule_data[0]['operand'] self.rule.operator.data = rule_data[0]['data'] if self._is_regex(self.rule.operator.data): self.rule.operator.type = "regexp" if self.ruleNameEdit.text() == "": self.rule.name = slugify( "%s %s %s" % (self.rule.action, self.rule.operator.type, self.rule.operator.data)) return True, ""
def _save_rule(self): """ Create a new rule based on the fields selected. Ensure that some constraints are met: - Determine if a field can be a regexp. - Validate regexp. - Fields cam not be empty. - If the user has not provided a rule name, auto assign one. """ self.rule = ui_pb2.Rule() self.rule.name = self.ruleNameEdit.text() self.rule.enabled = self.enableCheck.isChecked() self.rule.precedence = self.precedenceCheck.isChecked() self.rule.action = "deny" if self.actionDenyRadio.isChecked( ) else "allow" self.rule.duration = self.durationCombo.currentText() self.rule.operator.type = "simple" # FIXME: there should be a sensitive checkbox per operand self.rule.operator.sensitive = self.sensitiveCheck.isChecked() rule_data = [] if self.protoCheck.isChecked(): if self.protoCombo.currentText() == "": return False, "Protocol can not be empty" self.rule.operator.operand = "protocol" self.rule.operator.data = self.protoCombo.currentText() rule_data.append({ "type": "simple", "operand": "protocol", "data": self.protoCombo.currentText().lower(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.protoCombo.currentText()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex( self.protoCombo.currentText()) == False: return False, "Protocol error: invalid regular expression" if self.procCheck.isChecked(): if self.procLine.text() == "": return False, "Process path can not be empty" self.rule.operator.operand = "process.path" self.rule.operator.data = self.procLine.text() rule_data.append({ "type": "simple", "operand": "process.path", "data": self.procLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.procLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.procLine.text()) == False: return False, "Process path regexp error" if self.cmdlineCheck.isChecked(): if self.cmdlineLine.text() == "": return False, "Command line can not be empty" self.rule.operator.operand = "process.command" self.rule.operator.data = self.cmdlineLine.text() rule_data.append({ 'type': 'simple', 'operand': 'process.command', 'data': self.cmdlineLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.cmdlineLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.cmdlineLine.text()) == False: return False, "Command line regexp error" if self.dstPortCheck.isChecked(): if self.dstPortLine.text() == "": return False, "Destination port can not be empty" self.rule.operator.operand = "dest.port" self.rule.operator.data = self.dstPortLine.text() rule_data.append({ 'type': 'simple', 'operand': 'dest.port', 'data': self.dstPortLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.dstPortLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.dstPortLine.text()) == False: return False, "Destination port error: regular expression not valid" if self.dstHostCheck.isChecked(): if self.dstHostLine.text() == "": return False, "Destination host can not be empty" self.rule.operator.operand = "dest.host" self.rule.operator.data = self.dstHostLine.text() rule_data.append({ 'type': 'simple', 'operand': 'dest.host', 'data': self.dstHostLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.dstHostLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.dstHostLine.text()) == False: return False, "Destination host error: regular expression not valid" if self.dstIPCheck.isChecked(): if self.dstIPCombo.currentText() == "": return False, "Destination IP/Network can not be empty" dstIPtext = self.dstIPCombo.currentText() if dstIPtext == self.LAN_LABEL: self.rule.operator.operand = "dest.ip" self.rule.operator.type = "regexp" dstIPtext = self.LAN_RANGES else: try: if type(ipaddress.ip_address(self.dstIPCombo.currentText())) == ipaddress.IPv4Address \ or type(ipaddress.ip_address(self.dstIPCombo.currentText())) == ipaddress.IPv6Address: self.rule.operator.operand = "dest.ip" self.rule.operator.type = "simple" except Exception: self.rule.operator.operand = "dest.network" self.rule.operator.type = "network" if self._is_regex(dstIPtext): self.rule.operator.type = "regexp" if self._is_valid_regex( self.dstIPCombo.currentText()) == False: return False, "Destination IP error: regular expression not valid" rule_data.append({ 'type': self.rule.operator.type, 'operand': self.rule.operator.operand, 'data': dstIPtext, "sensitive": self.sensitiveCheck.isChecked() }) if self.uidCheck.isChecked(): if self.uidLine.text() == "": return False, "User ID can not be empty" self.rule.operator.operand = "user.id" self.rule.operator.data = self.uidLine.text() rule_data.append({ 'type': 'simple', 'operand': 'user.id', 'data': self.uidLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.uidLine.text()): rule_data[len(rule_data) - 1]['type'] = "regexp" if self._is_valid_regex(self.uidLine.text()) == False: return False, "User ID error: invalid regular expression" 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: self.rule.operator.operand = rule_data[0]['operand'] self.rule.operator.data = rule_data[0]['data'] if self._is_regex(self.rule.operator.data): self.rule.operator.type = "regexp" if self.ruleNameEdit.text() == "": self.rule.name = slugify( "%s %s %s" % (self.rule.action, self.rule.operator.type, self.rule.operator.data)) return True, ""