diff options
Diffstat (limited to 'lib/python2.7/site-packages/setools/policyrep/terule.py')
-rwxr-xr-x[-rw-r--r--] | lib/python2.7/site-packages/setools/policyrep/terule.py | 128 |
1 files changed, 113 insertions, 15 deletions
diff --git a/lib/python2.7/site-packages/setools/policyrep/terule.py b/lib/python2.7/site-packages/setools/policyrep/terule.py index 7fe56cc..fd5b1e1 100644..100755 --- a/lib/python2.7/site-packages/setools/policyrep/terule.py +++ b/lib/python2.7/site-packages/setools/policyrep/terule.py @@ -29,7 +29,10 @@ def te_rule_factory(policy, symbol): """Factory function for creating TE rule objects.""" if isinstance(symbol, qpol.qpol_avrule_t): - return AVRule(policy, symbol) + if symbol.is_extended(policy): + return AVRuleXperm(policy, symbol) + else: + return AVRule(policy, symbol) elif isinstance(symbol, (qpol.qpol_terule_t, qpol.qpol_filename_trans_t)): return TERule(policy, symbol) else: @@ -45,12 +48,14 @@ def expanded_te_rule_factory(original, source, target): target The target type of the expanded rule. """ - if isinstance(original, AVRule): + if isinstance(original, (ExpandedAVRule, ExpandedAVRuleXperm, ExpandedTERule)): + return original + elif isinstance(original, AVRuleXperm): + rule = ExpandedAVRuleXperm(original.policy, original.qpol_symbol) + elif isinstance(original, AVRule): rule = ExpandedAVRule(original.policy, original.qpol_symbol) elif isinstance(original, TERule): rule = ExpandedTERule(original.policy, original.qpol_symbol) - elif isinstance(original, (ExpandedAVRule, ExpandedTERule)): - return original else: raise TypeError("The original rule must be a TE rule class.") @@ -63,7 +68,8 @@ def expanded_te_rule_factory(original, source, target): def validate_ruletype(t): """Validate TE Rule types.""" if t not in ["allow", "auditallow", "dontaudit", "neverallow", - "type_transition", "type_member", "type_change"]: + "type_transition", "type_member", "type_change", + "allowxperm", "auditallowxperm", "dontauditxperm", "neverallowxperm"]: raise exception.InvalidTERuleType("{0} is not a valid TE rule type.".format(t)) return t @@ -92,10 +98,7 @@ class BaseTERule(rule.PolicyRule): """The rule's conditional expression.""" try: return boolcond.condexpr_factory(self.policy, self.qpol_symbol.cond(self.policy)) - except (AttributeError, ValueError): - # AttributeError: name filetrans rules cannot be conditional - # so no member function - # ValueError: The rule is not conditional + except AttributeError: raise exception.RuleNotConditional @property @@ -103,10 +106,7 @@ class BaseTERule(rule.PolicyRule): """The conditional block of the rule (T/F)""" try: return bool(self.qpol_symbol.which_list(self.policy)) - except (AttributeError, ValueError): - # AttributeError: name filetrans rules cannot be conditional - # so no member function - # ValueError: The rule is not conditional + except AttributeError: raise exception.RuleNotConditional def expand(self): @@ -125,9 +125,8 @@ class AVRule(BaseTERule): except AttributeError: self._rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} ".format(self) - perms = self.perms - # allow/dontaudit/auditallow/neverallow rules + perms = self.perms if len(perms) > 1: self._rule_string += "{{ {0} }};".format(' '.join(perms)) else: @@ -156,6 +155,96 @@ class AVRule(BaseTERule): raise exception.RuleUseError("{0} rules do not have file names".format(self.ruletype)) +class ioctlSet(set): + + """ + A set with overridden string functions which compresses + the output into ioctl ranges instead of individual elements. + """ + + def __format__(self, spec): + """ + String formating. + + The standard formatting (no specification) will render the + ranges of ioctls, space separated. + + The , option by itself will render the ranges of ioctls, + comma separated + + Any other combination of formatting options will fall back + to set's formatting behavior. + """ + + # generate short permission notation + perms = sorted(self) + shortlist = [] + for _, i in itertools.groupby(perms, key=lambda k, c=itertools.count(): k - next(c)): + group = list(i) + if len(group) > 1: + shortlist.append("{0:#06x}-{1:#06x}".format(group[0], group[-1])) + else: + shortlist.append("{0:#06x}".format(group[0])) + + if not spec: + return " ".join(shortlist) + elif spec == ",": + return ", ".join(shortlist) + else: + return super(ioctlSet, self).__format__(spec) + + def __str__(self): + return "{0}".format(self) + + def __repr__(self): + return "{{ {0:,} }}".format(self) + + def ranges(self): + """ + Return the number of ranges in the set. Main use + is to determine if brackets need to be used in + string output. + """ + return sum(1 for (_a, _b) in itertools.groupby( + sorted(self), key=lambda k, c=itertools.count(): k - next(c))) + + +class AVRuleXperm(AVRule): + + """An extended permission access vector type enforcement rule.""" + + extended = True + + def __hash__(self): + return hash("{0.ruletype}|{0.source}|{0.target}|{0.tclass}|{0.xperm_type}".format(self)) + + def __str__(self): + try: + return self._rule_string + except AttributeError: + self._rule_string = "{0.ruletype} {0.source} {0.target}:{0.tclass} {0.xperm_type} ". \ + format(self) + + # generate short permission notation + perms = self.perms + if perms.ranges() > 1: + self._rule_string += "{{ {0} }};".format(perms) + else: + self._rule_string += "{0};".format(perms) + + return self._rule_string + + @property + def perms(self): + """The rule's extended permission set.""" + return ioctlSet(self.qpol_symbol.xperm_iter(self.policy)) + + @property + def xperm_type(self): + """The standard permission extended by these permissions (e.g. ioctl).""" + return self.qpol_symbol.xperm_type(self.policy) + + class TERule(BaseTERule): """A type_* type enforcement rule.""" @@ -229,6 +318,15 @@ class ExpandedAVRule(AVRule): origin = None +class ExpandedAVRuleXperm(AVRuleXperm): + + """An expanded extended permission access vector type enforcement rule.""" + + source = None + target = None + origin = None + + class ExpandedTERule(TERule): """An expanded type_* type enforcement rule.""" |