def get_rule_from_records(self, records): rule = ui_pb2.Rule(name=records.value(2)) rule.enabled = self._bool(records.value(3)) rule.precedence = self._bool(records.value(4)) rule.action = records.value(5) rule.duration = records.value(6) rule.operator.type = records.value(7) rule.operator.sensitive = self._bool(records.value(8)) rule.operator.operand = records.value(9) rule.operator.data = "" if records.value(10) == None else str(records.value(10)) return rule
def delete_rule(self, rule_name, addr, callback): rule = ui_pb2.Rule(name=rule_name) rule.enabled = False rule.action = "" rule.duration = "" rule.operator.type = "" rule.operator.operand = "" rule.operator.data = "" noti = ui_pb2.Notification(type=ui_pb2.DELETE_RULE, rules=[rule]) nid = self.send_notification(addr, noti, None) self._db.delete_rule(rule.name, addr) return nid, noti
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 cannot 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.description = self.ruleDescEdit.toPlainText() self.rule.enabled = self.enableCheck.isChecked() self.rule.precedence = self.precedenceCheck.isChecked() self.rule.operator.type = Config.RULE_TYPE_SIMPLE self.rule.action = Config.ACTION_DENY if self.actionAllowRadio.isChecked(): self.rule.action = Config.ACTION_ALLOW elif self.actionRejectRadio.isChecked(): self.rule.action = Config.ACTION_REJECT self.rule.duration = self._get_duration( self.durationCombo.currentIndex()) # 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, QC.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": Config.RULE_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'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex( self.protoCombo.currentText()) == False: return False, QC.translate("rules", "Protocol regexp error") if self.procCheck.isChecked(): if self.procLine.text() == "": return False, QC.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": Config.RULE_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'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex(self.procLine.text()) == False: return False, QC.translate("rules", "Process path regexp error") if self.cmdlineCheck.isChecked(): if self.cmdlineLine.text() == "": return False, QC.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': Config.RULE_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'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex(self.cmdlineLine.text()) == False: return False, QC.translate("rules", "Command line regexp error") if self.dstPortCheck.isChecked(): if self.dstPortLine.text() == "": return False, QC.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': Config.RULE_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'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex(self.dstPortLine.text()) == False: return False, QC.translate("rules", "Dst port regexp error") if self.dstHostCheck.isChecked(): if self.dstHostLine.text() == "": return False, QC.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': Config.RULE_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'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex(self.dstHostLine.text()) == False: return False, QC.translate("rules", "Dst host regexp error") if self.dstIPCheck.isChecked(): if self.dstIPCombo.currentText() == "": return False, QC.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 = Config.RULE_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 = Config.RULE_TYPE_SIMPLE except Exception: self.rule.operator.operand = "dest.network" self.rule.operator.type = Config.RULE_TYPE_NETWORK if self._is_regex(dstIPtext): self.rule.operator.operand = "dest.ip" self.rule.operator.type = Config.RULE_TYPE_REGEXP if self._is_valid_regex( self.dstIPCombo.currentText()) == False: return False, QC.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, QC.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': Config.RULE_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'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex(self.uidLine.text()) == False: return False, QC.translate("rules", "User ID regexp error") if self.pidCheck.isChecked(): if self.pidLine.text() == "": return False, QC.translate("rules", "PID field can not be empty") self.rule.operator.operand = "process.id" self.rule.operator.data = self.pidLine.text() rule_data.append({ 'type': Config.RULE_TYPE_SIMPLE, 'operand': 'process.id', 'data': self.pidLine.text(), "sensitive": self.sensitiveCheck.isChecked() }) if self._is_regex(self.pidLine.text()): rule_data[len(rule_data) - 1]['type'] = Config.RULE_TYPE_REGEXP if self._is_valid_regex(self.pidLine.text()) == False: return False, QC.translate("rules", "PID field 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 = Config.RULE_TYPE_LISTS self.rule.operator.operand = "lists.domains" rule_data.append({ 'type': Config.RULE_TYPE_LISTS, 'operand': 'lists.domains', 'data': self.dstListsLine.text(), 'sensitive': self.sensitiveCheck.isChecked() }) self.rule.operator.data = json.dumps(rule_data) if self.dstListRegexpCheck.isChecked(): if self.dstRegexpListsLine.text() == "": return False, QC.translate("rules", "Lists field cannot be empty") if os.path.isdir(self.dstRegexpListsLine.text()) == False: return False, QC.translate("rules", "Lists field must be a directory") self.rule.operator.type = Config.RULE_TYPE_LISTS self.rule.operator.operand = "lists.domains_regexp" rule_data.append({ 'type': Config.RULE_TYPE_LISTS, 'operand': 'lists.domains_regexp', 'data': self.dstRegexpListsLine.text(), 'sensitive': self.sensitiveCheck.isChecked() }) self.rule.operator.data = json.dumps(rule_data) if self.dstListNetsCheck.isChecked(): if self.dstListNetsLine.text() == "": return False, QC.translate("rules", "Lists field cannot be empty") if os.path.isdir(self.dstListNetsLine.text()) == False: return False, QC.translate("rules", "Lists field must be a directory") self.rule.operator.type = Config.RULE_TYPE_LISTS self.rule.operator.operand = "lists.nets" rule_data.append({ 'type': Config.RULE_TYPE_LISTS, 'operand': 'lists.nets', 'data': self.dstListNetsLine.text(), 'sensitive': self.sensitiveCheck.isChecked() }) self.rule.operator.data = json.dumps(rule_data) if self.dstListIPsCheck.isChecked(): if self.dstListIPsLine.text() == "": return False, QC.translate("rules", "Lists field cannot be empty") if os.path.isdir(self.dstListIPsLine.text()) == False: return False, QC.translate("rules", "Lists field must be a directory") self.rule.operator.type = Config.RULE_TYPE_LISTS self.rule.operator.operand = "lists.ips" rule_data.append({ 'type': Config.RULE_TYPE_LISTS, 'operand': 'lists.ips', 'data': self.dstListIPsLine.text(), 'sensitive': self.sensitiveCheck.isChecked() }) self.rule.operator.data = json.dumps(rule_data) if len(rule_data) >= 2: self.rule.operator.type = Config.RULE_TYPE_LIST self.rule.operator.operand = Config.RULE_TYPE_LIST 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 = Config.RULE_TYPE_REGEXP else: return False, QC.translate("rules", "Select at least one field.") 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 _send_rule(self): try: 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 return rule_temp_name = self._get_rule_name(self._rule) self._rule.name = rule_temp_name # TODO: move to a method data = [] if 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.checkDstPort.isChecked( ) and self.whatCombo.itemData(what_idx) != self.FIELD_DST_PORT: data.append({ "type": Config.RULE_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.checkUserID.isChecked( ) and self.whatCombo.itemData(what_idx) != self.FIELD_USER_ID: data.append({ "type": Config.RULE_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._is_list_rule(): 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 = Config.RULE_TYPE_LIST self._rule.operator.operand = Config.RULE_TYPE_LIST self._rule.name = rule_temp_name self.hide() if self._ischeckAdvanceded: self.checkAdvanced.toggle() self._ischeckAdvanceded = False except Exception as e: print("[pop-up] exception creating a rule:", e) finally: # signal that the user took a decision and # a new rule is available self._done.set() self.hide()
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 cannot 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, QC.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, QC.translate("rules", "Protocol regexp error") if self.procCheck.isChecked(): if self.procLine.text() == "": return False, QC.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, QC.translate("rules", "Process path regexp error") if self.cmdlineCheck.isChecked(): if self.cmdlineLine.text() == "": return False, QC.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, QC.translate("rules", "Command line regexp error") if self.dstPortCheck.isChecked(): if self.dstPortLine.text() == "": return False, QC.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, QC.translate("rules", "Dst port regexp error") if self.dstHostCheck.isChecked(): if self.dstHostLine.text() == "": return False, QC.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, QC.translate("rules", "Dst host regexp error") if self.dstIPCheck.isChecked(): if self.dstIPCombo.currentText() == "": return False, QC.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.operand = "dest.ip" self.rule.operator.type = "regexp" if self._is_valid_regex( self.dstIPCombo.currentText()) == False: return False, QC.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, QC.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, 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 = "list" self.rule.operator.data = json.dumps(rule_data) 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): 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, ""