1 # Copyright 2014, 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 # 19 from . import exception 20 from . import qpol 21 from . import rule 22 from . import typeattr 23 from . import boolcond 24 25 26 def te_rule_factory(policy, symbol): 27 """Factory function for creating TE rule objects.""" 28 29 if isinstance(symbol, qpol.qpol_avrule_t): 30 return AVRule(policy, symbol) 31 elif isinstance(symbol, (qpol.qpol_terule_t, qpol.qpol_filename_trans_t)): 32 return TERule(policy, symbol) 33 else: 34 raise TypeError("TE rules cannot be looked-up.") 35 36 37 def validate_ruletype(types): 38 """Validate TE Rule types.""" 39 for t in types: 40 if t not in ["allow", "auditallow", "dontaudit", "neverallow", 41 "type_transition", "type_member", "type_change"]: 42 raise exception.InvalidTERuleType("{0} is not a valid TE rule type.".format(t)) 43 44 45 class BaseTERule(rule.PolicyRule): 46 47 """A type enforcement rule.""" 48 49 @property 50 def source(self): 51 """The rule's source type/attribute.""" 52 return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.source_type(self.policy)) 53 54 @property 55 def target(self): 56 """The rule's target type/attribute.""" 57 return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.target_type(self.policy)) 58 59 @property 60 def filename(self): 61 raise NotImplementedError 62 63 @property 64 def conditional(self): 65 """The rule's conditional expression.""" 66 try: 67 return boolcond.condexpr_factory(self.policy, self.qpol_symbol.cond(self.policy)) 68 except (AttributeError, ValueError): 69 # AttributeError: name filetrans rules cannot be conditional 70 # so no member function 71 # ValueError: The rule is not conditional 72 raise exception.RuleNotConditional 73 74 75 class AVRule(BaseTERule): 76 77 """An access vector type enforcement rule.""" 78 79 def __str__(self): 80 rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} ".format( 81 self) 82 83 perms = self.perms 84 85 # allow/dontaudit/auditallow/neverallow rules 86 if len(perms) > 1: 87 rule_string += "{{ {0} }};".format(' '.join(perms)) 88 else: 89 # convert to list since sets cannot be indexed 90 rule_string += "{0};".format(list(perms)[0]) 91 92 try: 93 rule_string += " [ {0} ]".format(self.conditional) 94 except exception.RuleNotConditional: 95 pass 96 97 return rule_string 98 99 @property 100 def perms(self): 101 """The rule's permission set.""" 102 return set(self.qpol_symbol.perm_iter(self.policy)) 103 104 @property 105 def default(self): 106 """The rule's default type.""" 107 raise exception.RuleUseError("{0} rules do not have a default type.".format(self.ruletype)) 108 109 @property 110 def filename(self): 111 raise exception.RuleUseError("{0} rules do not have file names".format(self.ruletype)) 112 113 114 class TERule(BaseTERule): 115 116 """A type_* type enforcement rule.""" 117 118 def __str__(self): 119 rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default}".format(self) 120 121 try: 122 rule_string += " \"{0}\";".format(self.filename) 123 except (exception.TERuleNoFilename, exception.RuleUseError): 124 # invalid use for type_change/member 125 rule_string += ";" 126 127 try: 128 rule_string += " [ {0} ]".format(self.conditional) 129 except exception.RuleNotConditional: 130 pass 131 132 return rule_string 133 134 @property 135 def perms(self): 136 """The rule's permission set.""" 137 raise exception.RuleUseError( 138 "{0} rules do not have a permission set.".format(self.ruletype)) 139 140 @property 141 def default(self): 142 """The rule's default type.""" 143 return typeattr.type_factory(self.policy, self.qpol_symbol.default_type(self.policy)) 144 145 @property 146 def filename(self): 147 """The type_transition rule's file name.""" 148 try: 149 return self.qpol_symbol.filename(self.policy) 150 except AttributeError: 151 if self.ruletype == "type_transition": 152 raise exception.TERuleNoFilename 153 else: 154 raise exception.RuleUseError("{0} rules do not have file names". 155 format(self.ruletype)) 156