Home | History | Annotate | Download | only in policyrep
      1 # Copyright 2014, 2016, 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 import itertools
     20 
     21 from . import exception
     22 from . import qpol
     23 from . import rule
     24 from . import typeattr
     25 from . import mls
     26 
     27 
     28 def mls_rule_factory(policy, symbol):
     29     """Factory function for creating MLS rule objects."""
     30     if not isinstance(symbol, qpol.qpol_range_trans_t):
     31         raise TypeError("MLS rules cannot be looked-up.")
     32 
     33     return MLSRule(policy, symbol)
     34 
     35 
     36 def expanded_mls_rule_factory(original, source, target):
     37     """
     38     Factory function for creating expanded MLS rules.
     39 
     40     original    The MLS rule the expanded rule originates from.
     41     source      The source type of the expanded rule.
     42     target      The target type of the expanded rule.
     43     """
     44 
     45     if isinstance(original, ExpandedMLSRule):
     46         return original
     47     elif isinstance(original, MLSRule):
     48         rule = ExpandedMLSRule(original.policy, original.qpol_symbol)
     49     else:
     50         raise TypeError("The original rule must be a MLS rule class.")
     51 
     52     rule.source = source
     53     rule.target = target
     54     rule.origin = original
     55     return rule
     56 
     57 
     58 def validate_ruletype(t):
     59     """Validate MLS rule types."""
     60     if t not in ["range_transition"]:
     61         raise exception.InvalidMLSRuleType("{0} is not a valid MLS rule type.".format(t))
     62 
     63     return t
     64 
     65 
     66 class MLSRule(rule.PolicyRule):
     67 
     68     """An MLS rule."""
     69 
     70     def __str__(self):
     71         return "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.default};".format(self)
     72 
     73     ruletype = "range_transition"
     74 
     75     @property
     76     def source(self):
     77         """The rule's source type/attribute."""
     78         return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.source_type(self.policy))
     79 
     80     @property
     81     def target(self):
     82         """The rule's target type/attribute."""
     83         return typeattr.type_or_attr_factory(self.policy, self.qpol_symbol.target_type(self.policy))
     84 
     85     @property
     86     def default(self):
     87         """The rule's default range."""
     88         return mls.range_factory(self.policy, self.qpol_symbol.range(self.policy))
     89 
     90     def expand(self):
     91         """Expand the rule into an equivalent set of rules without attributes."""
     92         for s, t in itertools.product(self.source.expand(), self.target.expand()):
     93             yield expanded_mls_rule_factory(self, s, t)
     94 
     95 
     96 class ExpandedMLSRule(MLSRule):
     97 
     98     """An expanded MLS rule."""
     99 
    100     source = None
    101     target = None
    102     origin = None
    103