Home | History | Annotate | Download | only in policyrep
      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