diff --git a/libapol/policyrep/__init__.py b/libapol/policyrep/__init__.py index 8b1b755..ae0e66f 100644 --- a/libapol/policyrep/__init__.py +++ b/libapol/policyrep/__init__.py @@ -79,6 +79,23 @@ class SELinuxPolicy(object): # # Policy components generators # + + def classes(self): + """Generator which yields all object classes.""" + + qiter = self.policy.get_class_iter() + while not qiter.end(): + yield objclass.ObjClass(self.policy, qpol.qpol_class_from_void(qiter.get_item())) + qiter.next() + + def commons(self): + """Generator which yields all commons.""" + + qiter = self.policy.get_common_iter() + while not qiter.end(): + yield objclass.Common(self.policy, qpol.qpol_common_from_void(qiter.get_item())) + qiter.next() + def types(self): """Generator which yields all types.""" diff --git a/libapol/policyrep/objclass.py b/libapol/policyrep/objclass.py index 0d8ed10..f9e2dab 100644 --- a/libapol/policyrep/objclass.py +++ b/libapol/policyrep/objclass.py @@ -23,10 +23,85 @@ import setools.qpol as qpol class Common(symbol.PolicySymbol): """A common permission set.""" + + def __contains__(self, other): + piter = self.qpol_symbol.get_perm_iter(self.policy) + + while not piter.end(): + if other == qpol.to_str(piter.get_item()): + return True + + piter.next() + + return False + + @property + def perms(self): + """The list of the common's permissions.""" + + piter = self.qpol_symbol.get_perm_iter(self.policy) + p = [] + + while not piter.end(): + p.append(qpol.to_str(piter.get_item())) + piter.next() + + return p + + def statement(self): + return "common {0}\n{{\n\t{1}\n}}".format(self, '\n\t'.join(self.perms)) + + @property + def value(self): + """ + The value of the common. + + This is a low-level policy detail exposed so that commons can + be sorted based on their policy declaration order instead of + by their name. This has no other use. + + Example usage: sorted(policy.commons(), key=lambda k: k.value) + """ + return self.qpol_symbol.get_value(self.policy) + + +class NoCommon(symbol.InvalidSymbol): + + """ + Exception when a class does not inherit a common permission set. + """ pass -class ObjClass(symbol.PolicySymbol): +class ObjClass(Common): """An object class.""" - pass + + @property + def common(self): + """ + The common that the object class inherits. + + Exceptions: + NoCommon The object class does not inherit a common. + """ + + try: + return Common(self.policy, self.qpol_symbol.get_common(self.policy)) + except symbol.InvalidSymbol: + raise NoCommon("{0} does not inherit a common.".format(self)) + + def statement(self): + stmt = "class {0}\n".format(self) + + try: + stmt += "inherits {0}\n".format(self.common) + except NoCommon: + pass + + # a class that inherits may not have additional permissions + perms = self.perms + if len(perms) > 0: + stmt += "{{\n\t{0}\n}}".format('\n\t'.join(perms)) + + return stmt