1# Copyright 2014-2015, Tresys Technology, LLC 2# 3# This file is part of SETools. 4# 5# SETools is free software: you can redistribute it and/or modify 6# it under the terms of the GNU Lesser General Public License as 7# published by the Free Software Foundation, either version 2.1 of 8# the License, or (at your option) any later version. 9# 10# SETools is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public 16# License along with SETools. If not, see 17# <http://www.gnu.org/licenses/>. 18# 19import logging 20import re 21 22from . import mixins, query 23from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor, RuletypeDescriptor 24from .policyrep.exception import RuleUseError, RuleNotConditional 25 26 27class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuery): 28 29 """ 30 Query the Type Enforcement rules. 31 32 Parameter: 33 policy The policy to query. 34 35 Keyword Parameters/Class attributes: 36 ruletype The list of rule type(s) to match. 37 source The name of the source type/attribute to match. 38 source_indirect If true, members of an attribute will be 39 matched rather than the attribute itself. 40 Default is true. 41 source_regex If true, regular expression matching will 42 be used on the source type/attribute. 43 Obeys the source_indirect option. 44 Default is false. 45 target The name of the target type/attribute to match. 46 target_indirect If true, members of an attribute will be 47 matched rather than the attribute itself. 48 Default is true. 49 target_regex If true, regular expression matching will 50 be used on the target type/attribute. 51 Obeys target_indirect option. 52 Default is false. 53 tclass The object class(es) to match. 54 tclass_regex If true, use a regular expression for 55 matching the rule's object class. 56 Default is false. 57 perms The set of permission(s) to match. 58 perms_equal If true, the permission set of the rule 59 must exactly match the permissions 60 criteria. If false, any set intersection 61 will match. 62 Default is false. 63 perms_regex If true, regular expression matching will be used 64 on the permission names instead of set logic. 65 default The name of the default type to match. 66 default_regex If true, regular expression matching will be 67 used on the default type. 68 Default is false. 69 boolean The set of boolean(s) to match. 70 boolean_regex If true, regular expression matching will be 71 used on the booleans. 72 Default is false. 73 boolean_equal If true, the booleans in the conditional 74 expression of the rule must exactly match the 75 criteria. If false, any set intersection 76 will match. Default is false. 77 """ 78 79 ruletype = RuletypeDescriptor("validate_te_ruletype") 80 source = CriteriaDescriptor("source_regex", "lookup_type_or_attr") 81 source_regex = False 82 source_indirect = True 83 target = CriteriaDescriptor("target_regex", "lookup_type_or_attr") 84 target_regex = False 85 target_indirect = True 86 default = CriteriaDescriptor("default_regex", "lookup_type") 87 default_regex = False 88 boolean = CriteriaSetDescriptor("boolean_regex", "lookup_boolean") 89 boolean_regex = False 90 boolean_equal = False 91 92 def results(self): 93 """Generator which yields all matching TE rules.""" 94 self.log.info("Generating results from {0.policy}".format(self)) 95 self.log.debug("Ruletypes: {0.ruletype}".format(self)) 96 self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, " 97 "regex: {0.source_regex}".format(self)) 98 self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, " 99 "regex: {0.target_regex}".format(self)) 100 self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self)) 101 self.log.debug("Perms: {0.perms!r}, regex: {0.perms_regex}, eq: {0.perms_equal}". 102 format(self)) 103 self.log.debug("Default: {0.default!r}, regex: {0.default_regex}".format(self)) 104 self.log.debug("Boolean: {0.boolean!r}, eq: {0.boolean_equal}, " 105 "regex: {0.boolean_regex}".format(self)) 106 107 for rule in self.policy.terules(): 108 # 109 # Matching on rule type 110 # 111 if self.ruletype: 112 if rule.ruletype not in self.ruletype: 113 continue 114 115 # 116 # Matching on source type 117 # 118 if self.source and not self._match_indirect_regex( 119 rule.source, 120 self.source, 121 self.source_indirect, 122 self.source_regex): 123 continue 124 125 # 126 # Matching on target type 127 # 128 if self.target and not self._match_indirect_regex( 129 rule.target, 130 self.target, 131 self.target_indirect, 132 self.target_regex): 133 continue 134 135 # 136 # Matching on object class 137 # 138 if not self._match_object_class(rule): 139 continue 140 141 # 142 # Matching on permission set 143 # 144 try: 145 if not self._match_perms(rule): 146 continue 147 except RuleUseError: 148 continue 149 150 # 151 # Matching on default type 152 # 153 if self.default: 154 try: 155 if not self._match_regex( 156 rule.default, 157 self.default, 158 self.default_regex): 159 continue 160 except RuleUseError: 161 continue 162 163 # 164 # Match on Boolean in conditional expression 165 # 166 if self.boolean: 167 try: 168 if not self._match_regex_or_set( 169 rule.conditional.booleans, 170 self.boolean, 171 self.boolean_equal, 172 self.boolean_regex): 173 continue 174 except RuleNotConditional: 175 continue 176 177 # if we get here, we have matched all available criteria 178 yield rule 179