Home | History | Annotate | Download | only in setools
      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 #
     19 import logging
     20 
     21 from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
     22 from .mixins import MatchObjClass
     23 from .query import PolicyQuery
     24 from .util import match_indirect_regex, match_range
     25 
     26 
     27 class MLSRuleQuery(MatchObjClass, PolicyQuery):
     28 
     29     """
     30     Query MLS 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_regex     If true, regular expression matching will
     39                      be used on the source type/attribute.
     40     target           The name of the target type/attribute to match.
     41     target_regex     If true, regular expression matching will
     42                      be used on the target type/attribute.
     43     tclass           The object class(es) to match.
     44     tclass_regex     If true, use a regular expression for
     45                      matching the rule's object class.
     46     """
     47 
     48     ruletype = CriteriaSetDescriptor(lookup_function="validate_mls_ruletype")
     49     source = CriteriaDescriptor("source_regex", "lookup_type_or_attr")
     50     source_regex = False
     51     source_indirect = True
     52     target = CriteriaDescriptor("target_regex", "lookup_type_or_attr")
     53     target_regex = False
     54     target_indirect = True
     55     tclass = CriteriaSetDescriptor("tclass_regex", "lookup_class")
     56     tclass_regex = False
     57     default = CriteriaDescriptor(lookup_function="lookup_range")
     58     default_overlap = False
     59     default_subset = False
     60     default_superset = False
     61     default_proper = False
     62 
     63     def __init__(self, policy, **kwargs):
     64         super(MLSRuleQuery, self).__init__(policy, **kwargs)
     65         self.log = logging.getLogger(__name__)
     66 
     67     def results(self):
     68         """Generator which yields all matching MLS rules."""
     69         self.log.info("Generating MLS rule results from {0.policy}".format(self))
     70         self.log.debug("Ruletypes: {0.ruletype}".format(self))
     71         self.log.debug("Source: {0.source!r}, indirect: {0.source_indirect}, "
     72                        "regex: {0.source_regex}".format(self))
     73         self.log.debug("Target: {0.target!r}, indirect: {0.target_indirect}, "
     74                        "regex: {0.target_regex}".format(self))
     75         self._match_object_class_debug(self.log)
     76         self.log.debug("Default: {0.default!r}, overlap: {0.default_overlap}, "
     77                        "subset: {0.default_subset}, superset: {0.default_superset}, "
     78                        "proper: {0.default_proper}".format(self))
     79 
     80         for rule in self.policy.mlsrules():
     81             #
     82             # Matching on rule type
     83             #
     84             if self.ruletype:
     85                 if rule.ruletype not in self.ruletype:
     86                     continue
     87 
     88             #
     89             # Matching on source type
     90             #
     91             if self.source and not match_indirect_regex(
     92                     rule.source,
     93                     self.source,
     94                     self.source_indirect,
     95                     self.source_regex):
     96                 continue
     97 
     98             #
     99             # Matching on target type
    100             #
    101             if self.target and not match_indirect_regex(
    102                     rule.target,
    103                     self.target,
    104                     self.target_indirect,
    105                     self.target_regex):
    106                 continue
    107 
    108             #
    109             # Matching on object class
    110             #
    111             if not self._match_object_class(rule):
    112                 continue
    113 
    114             #
    115             # Matching on range
    116             #
    117             if self.default and not match_range(
    118                     rule.default,
    119                     self.default,
    120                     self.default_subset,
    121                     self.default_overlap,
    122                     self.default_superset,
    123                     self.default_proper):
    124                 continue
    125 
    126             # if we get here, we have matched all available criteria
    127             yield rule
    128