diff options
Diffstat (limited to 'lib/python2.7/site-packages/sepolgen/output.py')
-rw-r--r-- | lib/python2.7/site-packages/sepolgen/output.py | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/sepolgen/output.py b/lib/python2.7/site-packages/sepolgen/output.py new file mode 100644 index 0000000..7a83aee --- /dev/null +++ b/lib/python2.7/site-packages/sepolgen/output.py @@ -0,0 +1,177 @@ +# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> +# +# Copyright (C) 2006 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 only +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Classes and functions for the output of reference policy modules. + +This module takes a refpolicy.Module object and formats it for +output using the ModuleWriter object. By separating the output +in this way the other parts of Madison can focus solely on +generating policy. This keeps the semantic / syntactic issues +cleanly separated from the formatting issues. +""" + +from . import refpolicy +from . import util + +if util.PY3: + from .util import cmp + + +class ModuleWriter: + def __init__(self): + self.fd = None + self.module = None + self.sort = True + self.requires = True + + def write(self, module, fd): + self.module = module + + if self.sort: + sort_filter(self.module) + + # FIXME - make this handle nesting + for node, depth in refpolicy.walktree(self.module, showdepth=True): + fd.write("%s\n" % str(node)) + +# Helper functions for sort_filter - this is all done old school +# C style rather than with polymorphic methods because this sorting +# is specific to output. It is not necessarily the comparison you +# want generally. + +# Compare two IdSets - we could probably do something clever +# with different here, but this works. +def id_set_cmp(x, y): + xl = util.set_to_list(x) + xl.sort() + yl = util.set_to_list(y) + yl.sort() + + if len(xl) != len(yl): + return cmp(xl[0], yl[0]) + for v in zip(xl, yl): + if v[0] != v[1]: + return cmp(v[0], v[1]) + return 0 + +# Compare two avrules +def avrule_cmp(a, b): + ret = id_set_cmp(a.src_types, b.src_types) + if ret is not 0: + return ret + ret = id_set_cmp(a.tgt_types, b.tgt_types) + if ret is not 0: + return ret + ret = id_set_cmp(a.obj_classes, b.obj_classes) + if ret is not 0: + return ret + + # At this point, who cares - just return something + return cmp(len(a.perms), len(b.perms)) + +# Compare two interface calls +def ifcall_cmp(a, b): + if a.args[0] != b.args[0]: + return cmp(a.args[0], b.args[0]) + return cmp(a.ifname, b.ifname) + +# Compare an two avrules or interface calls +def rule_cmp(a, b): + if isinstance(a, refpolicy.InterfaceCall): + if isinstance(b, refpolicy.InterfaceCall): + return ifcall_cmp(a, b) + else: + return id_set_cmp([a.args[0]], b.src_types) + else: + if isinstance(b, refpolicy.AVRule): + return avrule_cmp(a,b) + else: + return id_set_cmp(a.src_types, [b.args[0]]) + +def role_type_cmp(a, b): + return cmp(a.role, b.role) + +def sort_filter(module): + """Sort and group the output for readability. + """ + def sort_node(node): + c = [] + + # Module statement + for mod in node.module_declarations(): + c.append(mod) + c.append(refpolicy.Comment()) + + # Requires + for require in node.requires(): + c.append(require) + c.append(refpolicy.Comment()) + + # Rules + # + # We are going to group output by source type (which + # we assume is the first argument for interfaces). + rules = [] + rules.extend(node.avrules()) + rules.extend(node.interface_calls()) + rules.sort(key=util.cmp_to_key(rule_cmp)) + + cur = None + sep_rules = [] + for rule in rules: + if isinstance(rule, refpolicy.InterfaceCall): + x = rule.args[0] + else: + x = util.first(rule.src_types) + + if cur != x: + if cur: + sep_rules.append(refpolicy.Comment()) + cur = x + comment = refpolicy.Comment() + comment.lines.append("============= %s ==============" % cur) + sep_rules.append(comment) + sep_rules.append(rule) + + c.extend(sep_rules) + + + ras = [] + ras.extend(node.role_types()) + ras.sort(key=util.cmp_to_key(role_type_cmp)) + if len(ras): + comment = refpolicy.Comment() + comment.lines.append("============= ROLES ==============") + c.append(comment) + + + c.extend(ras) + + # Everything else + for child in node.children: + if child not in c: + c.append(child) + + node.children = c + + for node in module.nodes(): + sort_node(node) + + |