113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Copyright (C) 2006 Red Hat
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# see file 'COPYING' for use and warranty information
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This program is free software; you can redistribute it and/or
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# modify it under the terms of the GNU General Public License as
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# published by the Free Software Foundation; version 2 only
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This program is distributed in the hope that it will be useful,
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# but WITHOUT ANY WARRANTY; without even the implied warranty of
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# GNU General Public License for more details.
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# You should have received a copy of the GNU General Public License
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# along with this program; if not, write to the Free Software
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport string
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport selinux
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# OVERVIEW
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This file contains objects and functions used to represent the reference
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# policy (including the headers, M4 macros, and policy language statements).
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This representation is very different from the semantic representation
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# used in libsepol. Instead, it is a more typical abstract representation
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# used by the first stage of compilers. It is basically a parse tree.
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This choice is intentional as it allows us to handle the unprocessed
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# M4 statements - including the $1 style arguments - and to more easily generate
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# the data structures that we need for policy generation.
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Constans for referring to fields
3813cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleSRC_TYPE  = 0
3913cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleTGT_TYPE  = 1
4013cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleOBJ_CLASS = 2
4113cd4c8960688af11ad23b4c946149015c80d54Joshua BrindlePERMS     = 3
4213cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleROLE      = 4
4313cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleDEST_TYPE = 5
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# String represenations of the above constants
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlefield_to_str = ["source", "target", "object", "permission", "role", "destination" ]
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestr_to_field = { "source" : SRC_TYPE, "target" : TGT_TYPE, "object" : OBJ_CLASS,
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                "permission" : PERMS, "role" : ROLE, "destination" : DEST_TYPE }
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Base Classes
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass PolicyBase:
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.parent = None
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.comment = None
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Node(PolicyBase):
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """Base class objects produced from parsing the reference policy.
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The Node class is used as the base class for any non-leaf
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    object produced by parsing the reference policy. This object
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    should contain a reference to its parent (or None for a top-level
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    object) and 0 or more children.
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The general idea here is to have a very simple tree structure. Children
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    are not separated out by type. Instead the tree structure represents
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    fairly closely the real structure of the policy statements.
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The object should be iterable - by default over all children but
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    subclasses are free to provide additional iterators over a subset
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    of their childre (see Interface for example).
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        PolicyBase.__init__(self, parent)
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.children = []
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __iter__(self):
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return iter(self.children)
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    # Not all of the iterators will return something on all Nodes, but
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    # they won't explode either. Putting them here is just easier.
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    # Top level nodes
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def nodes(self):
8715a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, Node), walktree(self))
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def modules(self):
9015a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, Module), walktree(self))
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def interfaces(self):
9315a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, Interface), walktree(self))
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def templates(self):
9615a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, Template), walktree(self))
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def support_macros(self):
9915a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, SupportMacros), walktree(self))
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    # Common policy statements
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def module_declarations(self):
10415a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, ModuleDeclaration), walktree(self))
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def interface_calls(self):
10715a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, InterfaceCall), walktree(self))
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def avrules(self):
11015a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, AVRule), walktree(self))
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def typerules(self):
11315a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, TypeRule), walktree(self))
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1159136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl    def typebounds(self):
1169136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl        return filter(lambda x: isinstance(x, TypeBound), walktree(self))
1179136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def typeattributes(self):
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Iterate over all of the TypeAttribute children of this Interface."""
12015a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, TypeAttribute), walktree(self))
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
1223dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    def roleattributes(self):
1233dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        """Iterate over all of the RoleAttribute children of this Interface."""
12415a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, RoleAttribute), walktree(self))
1253dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def requires(self):
12715a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, Require), walktree(self))
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def roles(self):
13015a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, Role), walktree(self))
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def role_allows(self):
13315a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, RoleAllow), walktree(self))
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def role_types(self):
13615a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return filter(lambda x: isinstance(x, RoleType), walktree(self))
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __str__(self):
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.comment:
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return str(self.comment) + "\n" + self.to_string()
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return self.to_string()
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __repr__(self):
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "<%s(%s)>" % (self.__class__.__name__, self.to_string())
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return ""
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Leaf(PolicyBase):
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        PolicyBase.__init__(self, parent)
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __str__(self):
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.comment:
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return str(self.comment) + "\n" + self.to_string()
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return self.to_string()
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __repr__(self):
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "<%s(%s)>" % (self.__class__.__name__, self.to_string())
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return ""
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Utility functions
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef walktree(node, depthfirst=True, showdepth=False, type=None):
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """Iterate over a Node and its Children.
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The walktree function iterates over a tree containing Nodes and
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    leaf objects. The iteration can perform a depth first or a breadth
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    first traversal of the tree (controlled by the depthfirst
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    paramater. The passed in node will be returned.
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    This function will only work correctly for trees - arbitrary graphs
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    will likely cause infinite looping.
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    # We control depth first / versus breadth first by
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    # how we pop items off of the node stack.
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if depthfirst:
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        index = -1
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    else:
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        index = 0
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    stack = [(node, 0)]
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    while len(stack) > 0:
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cur, depth = stack.pop(index)
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if showdepth:
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            yield cur, depth
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            yield cur
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # If the node is not a Node instance it must
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # be a leaf - so no need to add it to the stack
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if isinstance(cur, Node):
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            items = []
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            i = len(cur.children) - 1
20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            while i >= 0:
20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if type is None or isinstance(cur.children[i], type):
20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    items.append((cur.children[i], depth + 1))
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                i -= 1
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            stack.extend(items)
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef walknode(node, type=None):
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """Iterate over the direct children of a Node.
21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The walktree function iterates over the children of a Node.
21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    Unlike walktree it does note return the passed in node or
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    the children of any Node objects (that is, it does not go
21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    beyond the current level in the tree).
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for x in node:
21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if type is None or isinstance(x, type):
21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            yield x
22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef list_to_space_str(s, cont=('{', '}')):
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """Convert a set (or any sequence type) into a string representation
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    formatted to match SELinux space separated list conventions.
22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    For example the list ['read', 'write'] would be converted into:
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    '{ read write }'
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    l = len(s)
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    str = ""
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if l < 1:
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        raise ValueError("cannot convert 0 len set to string")
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    str = " ".join(s)
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if l == 1:
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return str
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    else:
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return cont[0] + " " + str + " " + cont[1]
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef list_to_comma_str(s):
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    l = len(s)
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if l < 1:
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        raise ValueError("cannot conver 0 len set to comma string")
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return ", ".join(s)
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Basic SELinux types
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass IdSet(set):
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, list=None):
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if list:
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            set.__init__(self, list)
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            set.__init__(self)
25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.compliment = False
25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_space_str(self):
257211baf74efbe0fdc87d7f9b86d931f43713a8538Nicolas Iooss        return list_to_space_str(sorted(self))
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_comma_str(self):
260211baf74efbe0fdc87d7f9b86d931f43713a8538Nicolas Iooss        return list_to_comma_str(sorted(self))
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass SecurityContext(Leaf):
26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """An SELinux security context with optional MCS / MLS fields."""
26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, context=None, parent=None):
26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Create a SecurityContext object, optionally from a string.
26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Parameters:
26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle           [context] - string representing a security context. Same format
26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle              as a string passed to the from_string method.
27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.user = ""
27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.role = ""
27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.type = ""
27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.level = None
27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if context is not None:
27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.from_string(context)
27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def from_string(self, context):
28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Parse a string representing a context into a SecurityContext.
28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        The string should be in the standard format - e.g.,
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        'user:role:type:level'.
28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Raises ValueError if the string is not parsable as a security context.
28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        fields = context.split(":")
28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(fields) < 3:
28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            raise ValueError("context string [%s] not in a valid format" % context)
29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.user = fields[0]
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.role = fields[1]
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.type = fields[2]
29413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(fields) > 3:
29513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            # FUTURE - normalize level fields to allow more comparisons to succeed.
29615a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska            self.level = ':'.join(fields[3:])
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.level = None
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __eq__(self, other):
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Compare two SecurityContext objects - all fields must be exactly the
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        the same for the comparison to work. It is possible for the level fields
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        to be semantically the same yet syntactically different - in this case
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        this function will return false.
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return self.user == other.user and \
30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle               self.role == other.role and \
30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle               self.type == other.type and \
30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle               self.level == other.level
31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self, default_level=None):
31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Return a string representing this security context.
31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        By default, the string will contiain a MCS / MLS level
31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        potentially from the default which is passed in if none was
31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        set.
31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Arguments:
31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle           default_level - the default level to use if self.level is an
32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle             empty string.
32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Returns:
32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle           A string represening the security context in the form
32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle              'user:role:type:level'.
32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        fields = [self.user, self.role, self.type]
32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.level is None:
32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if default_level is None:
32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if selinux.is_selinux_mls_enabled() == 1:
33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    fields.append("s0")
33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            else:
33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                fields.append(default_level)
33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            fields.append(self.level)
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return ":".join(fields)
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass ObjectClass(Leaf):
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """SELinux object class and permissions.
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    This class is a basic representation of an SELinux object
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    class - it does not represent separate common permissions -
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    just the union of the common and class specific permissions.
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    It is meant to be convenient for policy generation.
34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name="", parent=None):
34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.perms = IdSet()
34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Basic statements
35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass TypeAttribute(Leaf):
35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """SElinux typeattribute statement.
35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    This class represents a typeattribute statement.
35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.type = ""
36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.attributes = IdSet()
36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "typeattribute %s %s;" % (self.type, self.attributes.to_comma_str())
36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3653dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Greplclass RoleAttribute(Leaf):
3663dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    """SElinux roleattribute statement.
3673dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
3683dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    This class represents a roleattribute statement.
3693dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    """
3703dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    def __init__(self, parent=None):
3713dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        Leaf.__init__(self, parent)
3723dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        self.role = ""
3733dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        self.roleattributes = IdSet()
3743dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
3753dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    def to_string(self):
3763dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        return "roleattribute %s %s;" % (self.role, self.roleattributes.to_comma_str())
3773dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
3783dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Role(Leaf):
38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.role = ""
38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.types = IdSet()
38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
386a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris        s = ""
387a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris        for t in self.types:
388a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris            s += "role %s types %s;\n" % (self.role, t)
389a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris        return s
39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Type(Leaf):
39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name="", parent=None):
39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.attributes = IdSet()
39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.aliases = IdSet()
39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = "type %s" % self.name
40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(self.aliases) > 0:
40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s = s + "alias %s" % self.aliases.to_space_str()
40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(self.attributes) > 0:
40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s = s + ", %s" % self.attributes.to_comma_str()
40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return s + ";"
40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass TypeAlias(Leaf):
40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.type = ""
41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.aliases = IdSet()
41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "typealias %s alias %s;" % (self.type, self.aliases.to_space_str())
41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Attribute(Leaf):
41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name="", parent=None):
41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "attribute %s;" % self.name
42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4233dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Greplclass Attribute_Role(Leaf):
4243dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    def __init__(self, name="", parent=None):
4253dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        Leaf.__init__(self, parent)
4263dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        self.name = name
4273dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
4283dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl    def to_string(self):
4293dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl        return "attribute_role %s;" % self.name
4303dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
4313dd13f7d0859b3f8b97700f5c24651af4807af49Miroslav Grepl
43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Classes representing rules
43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass AVRule(Leaf):
43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """SELinux access vector (AV) rule.
43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The AVRule class represents all varieties of AV rules including
43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    allow, dontaudit, and auditallow (indicated by the flags self.ALLOW,
43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    self.DONTAUDIT, and self.AUDITALLOW respectively).
44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    The source and target types, object classes, and perms are all represented
44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    by sets containing strings. Sets are used to make it simple to add
44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    strings repeatedly while avoiding duplicates.
44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    No checking is done to make certain that the symbols are valid or
44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    consistent (e.g., perms that don't match the object classes). It is
44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    even possible to put invalid types like '$1' into the rules to allow
44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    storage of the reference policy interfaces.
44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    ALLOW = 0
45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    DONTAUDIT = 1
45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    AUDITALLOW = 2
45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    NEVERALLOW = 3
45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, av=None, parent=None):
45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.src_types = IdSet()
45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.tgt_types = IdSet()
45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.obj_classes = IdSet()
46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.perms = IdSet()
46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.rule_type = self.ALLOW
46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if av:
46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.from_av(av)
46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
46513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __rule_type_str(self):
46613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.rule_type == self.ALLOW:
46713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "allow"
46813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        elif self.rule_type == self.DONTAUDIT:
46913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "dontaudit"
47013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
47113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "auditallow"
47213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
47313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def from_av(self, av):
47413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Add the access from an access vector to this allow
47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rule.
47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
47713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.src_types.add(av.src_type)
47813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if av.src_type == av.tgt_type:
47913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.tgt_types.add("self")
48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.tgt_types.add(av.tgt_type)
48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.obj_classes.add(av.obj_class)
48313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.perms.update(av.perms)
48413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
48513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
48613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Return a string representation of the rule
48713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        that is a valid policy language representation (assuming
48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        that the types, object class, etc. are valie).
48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "%s %s %s:%s %s;" % (self.__rule_type_str(),
49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.src_types.to_space_str(),
49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.tgt_types.to_space_str(),
49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.obj_classes.to_space_str(),
49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.perms.to_space_str())
49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass TypeRule(Leaf):
49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """SELinux type rules.
49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    This class is very similar to the AVRule class, but is for representing
49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    the type rules (type_trans, type_change, and type_member). The major
50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    difference is the lack of perms and only and sing destination type.
50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    TYPE_TRANSITION = 0
50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    TYPE_CHANGE = 1
50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    TYPE_MEMBER = 2
50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.src_types = IdSet()
50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.tgt_types = IdSet()
51013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.obj_classes = IdSet()
51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.dest_type = ""
51213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.rule_type = self.TYPE_TRANSITION
51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __rule_type_str(self):
51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.rule_type == self.TYPE_TRANSITION:
51613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "type_transition"
51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        elif self.rule_type == self.TYPE_CHANGE:
51813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "type_change"
51913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
52013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "type_member"
52113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
52213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
52313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "%s %s %s:%s %s;" % (self.__rule_type_str(),
52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.src_types.to_space_str(),
52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.tgt_types.to_space_str(),
52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.obj_classes.to_space_str(),
52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     self.dest_type)
5289136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Greplclass TypeBound(Leaf):
5299136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl    """SElinux typebound statement.
5309136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl
5319136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl    This class represents a typebound statement.
5329136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl    """
5339136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl    def __init__(self, parent=None):
5349136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl        Leaf.__init__(self, parent)
5359136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl        self.type = ""
5369136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl        self.tgt_types = IdSet()
5379136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl
5389136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl    def to_string(self):
5399136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl        return "typebounds %s %s;" % (self.type, self.tgt_types.to_comma_str())
5409136e7a9bc2184badb8bc1aa95e58d4c086cedd7Miroslav Grepl
54113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
54213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass RoleAllow(Leaf):
54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
54413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
54513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.src_roles = IdSet()
54613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.tgt_roles = IdSet()
54713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
54813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
54913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "allow %s %s;" % (self.src_roles.to_comma_str(),
55013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                 self.tgt_roles.to_comma_str())
55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass RoleType(Leaf):
55313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.role = ""
55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.types = IdSet()
55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
559a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris        s = ""
560a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris        for t in self.types:
561a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris            s += "role %s types %s;\n" % (self.role, t)
562a8a36f88c2791171d798a33866f5da625a2deea1Eric Paris        return s
56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass ModuleDeclaration(Leaf):
56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = ""
56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.version = ""
56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.refpolicy = False
57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.refpolicy:
57313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "policy_module(%s, %s)" % (self.name, self.version)
57413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
57513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "module %s %s;" % (self.name, self.version)
57613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
57713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Conditional(Node):
57813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
57913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
58013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.cond_expr = []
58113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
58213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
58313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[If %s]" % list_to_space_str(self.cond_expr, cont=("", ""))
58413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
58513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Bool(Leaf):
58613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
58713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
58813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = ""
58913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.state = False
59013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
59113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
59213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = "bool %s " % self.name
59313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if s.state:
59413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return s + "true"
59513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
59613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return s + "false"
59713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
59813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass InitialSid(Leaf):
59913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init(self, parent=None):
60013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
60113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = ""
60213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.context = None
60313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
60413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
60513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "sid %s %s" % (self.name, str(self.context))
60613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
60713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass GenfsCon(Leaf):
60813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
60913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
61013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.filesystem = ""
61113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.path = ""
61213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.context = None
61313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
61413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
61513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "genfscon %s %s %s" % (self.filesystem, self.path, str(self.context))
61613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
61713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass FilesystemUse(Leaf):
61813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    XATTR = 1
61913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    TRANS = 2
62013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    TASK = 3
62113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
62213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
62313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
62413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.type = self.XATTR
62513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.filesystem = ""
62613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.context = None
62713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
62813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
62913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = ""
63013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.type == XATTR:
63113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s = "fs_use_xattr "
63213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        elif self.type == TRANS:
63313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s = "fs_use_trans "
63413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        elif self.type == TASK:
63513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s = "fs_use_task "
63613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
63713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "%s %s %s;" % (s, self.filesystem, str(self.context))
63813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
63913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass PortCon(Leaf):
64013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
64113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
64213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.port_type = ""
64313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.port_number = ""
64413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.context = None
64513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
64613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
64713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "portcon %s %s %s" % (self.port_type, self.port_number, str(self.context))
64813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
64913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass NodeCon(Leaf):
65013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
65113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
65213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.start = ""
65313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.end = ""
65413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.context = None
65513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
65613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
65713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "nodecon %s %s %s" % (self.start, self.end, str(self.context))
65813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
65913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass NetifCon(Leaf):
66013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
66113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
66213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.interface = ""
66313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.interface_context = None
66413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.packet_context = None
66513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
66613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
66713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "netifcon %s %s %s" % (self.interface, str(self.interface_context),
66813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                   str(self.packet_context))
6696341f6a4926b46f36ba9a05736460da53bd95557pjnuzziclass PirqCon(Leaf):
6706341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def __init__(self, parent=None):
6716341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        Leaf.__init__(self, parent)
6726341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.pirq_number = ""
6736341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.context = None
6746341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
6756341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def to_string(self):
6766341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        return "pirqcon %s %s" % (self.pirq_number, str(self.context))
6776341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
6786341f6a4926b46f36ba9a05736460da53bd95557pjnuzziclass IomemCon(Leaf):
6796341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def __init__(self, parent=None):
6806341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        Leaf.__init__(self, parent)
6816341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.device_mem = ""
6826341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.context = None
6836341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
6846341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def to_string(self):
6856341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        return "iomemcon %s %s" % (self.device_mem, str(self.context))
6866341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
6876341f6a4926b46f36ba9a05736460da53bd95557pjnuzziclass IoportCon(Leaf):
6886341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def __init__(self, parent=None):
6896341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        Leaf.__init__(self, parent)
6906341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.ioport = ""
6916341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.context = None
6926341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
6936341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def to_string(self):
6946341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        return "ioportcon %s %s" % (self.ioport, str(self.context))
6956341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
6966341f6a4926b46f36ba9a05736460da53bd95557pjnuzziclass PciDeviceCon(Leaf):
6976341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def __init__(self, parent=None):
6986341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        Leaf.__init__(self, parent)
6996341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.device = ""
7006341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        self.context = None
7016341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi
7026341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi    def to_string(self):
7036341f6a4926b46f36ba9a05736460da53bd95557pjnuzzi        return "pcidevicecon %s %s" % (self.device, str(self.context))
70413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
705f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graafclass DeviceTreeCon(Leaf):
706f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf    def __init__(self, parent=None):
707f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf        Leaf.__init__(self, parent)
708f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf        self.path = ""
709f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf        self.context = None
710f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf
711f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf    def to_string(self):
712f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf        return "devicetreecon %s %s" % (self.path, str(self.context))
713f0290677091e7eee4a3724a2a86ede9e11f93802Daniel De Graaf
71413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Reference policy specific types
71513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
71613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef print_tree(head):
71713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for node, depth in walktree(head, showdepth=True):
71813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = ""
71913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for i in range(depth):
72013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s = s + "\t"
72115a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        print(s + str(node))
72213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
72313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
72413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Headers(Node):
72513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
72613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
72713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
72813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
72913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Headers]"
73013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
73113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
73213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Module(Node):
73313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
73413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
73513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
73613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
73713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return ""
73813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
73913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Interface(Node):
74013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """A reference policy interface definition.
74113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
74213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    This class represents a reference policy interface definition.
74313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
74413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name="", parent=None):
74513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
74613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
74713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
74813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
74913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Interface name: %s]" % self.name
75013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
75113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass TunablePolicy(Node):
75213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
75313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
75413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.cond_expr = []
75513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
75613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
75713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Tunable Policy %s]" % list_to_space_str(self.cond_expr, cont=("", ""))
75813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
75913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Template(Node):
76013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name="", parent=None):
76113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
76213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
76313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
76413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
76513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Template name: %s]" % self.name
76613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
76713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass IfDef(Node):
76813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name="", parent=None):
76913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
77013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
77113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
77213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
77313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Ifdef name: %s]" % self.name
77413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
77513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass InterfaceCall(Leaf):
77613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, ifname="", parent=None):
77713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
77813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.ifname = ifname
77913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.args = []
78013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.comments = []
78113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
78213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def matches(self, other):
78313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if self.ifname != other.ifname:
78413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return False
78513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(self.args) != len(other.args):
78613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return False
78713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for a,b in zip(self.args, other.args):
78813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if a != b:
78913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                return False
79013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return True
79113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
79213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
79313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = "%s(" % self.ifname
79413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        i = 0
79513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for a in self.args:
79613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if isinstance(a, list):
79713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                str = list_to_space_str(a)
79813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            else:
79913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                str = a
80013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
80113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if i != 0:
80213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                s = s + ", %s" % str
80313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            else:
80413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                s = s + str
80513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            i += 1
80613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return s + ")"
80713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
80813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass OptionalPolicy(Node):
80913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
81013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
81113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
81213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
81313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Optional Policy]"
81413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
81513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass SupportMacros(Node):
81613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
81713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Node.__init__(self, parent)
81813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.map = None
81913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
82013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
82113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "[Support Macros]"
82213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
82313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __expand_perm(self, perm):
82413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # Recursive expansion - the assumption is that these
82513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # are ordered correctly so that no macro is used before
82613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # it is defined
82713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = set()
82815a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        if perm in self.map:
82913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for p in self.by_name(perm):
83013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                s.update(self.__expand_perm(p))
83113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
83213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s.add(perm)
83313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return s
83413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
83513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __gen_map(self):
83613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.map = {}
83713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for x in self:
83813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            exp_perms = set()
83913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for perm in x.perms:
84013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                exp_perms.update(self.__expand_perm(perm))
84113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.map[x.name] = exp_perms
84213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
84313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def by_name(self, name):
84413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if not self.map:
84513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.__gen_map()
84613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return self.map[name]
84713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
84813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def has_key(self, name):
84913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if not self.map:
85013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.__gen_map()
85115a7553d2274a351fb1098f7bfab86346c5a04b8Robert Kuska        return name in self.map
85213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
85313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Require(Leaf):
85413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, parent=None):
85513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Leaf.__init__(self, parent)
85613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.types = IdSet()
85713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.obj_classes = { }
85813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.roles = IdSet()
859628bcc69e23d96cec308bae5c70bebdeebeeeeccEric Paris        self.data = IdSet()
86013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.users = IdSet()
86113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
86213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def add_obj_class(self, obj_class, perms):
86313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        p = self.obj_classes.setdefault(obj_class, IdSet())
86413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        p.update(perms)
86513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
86613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
86713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
86813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s = []
86913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s.append("require {")
87013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for type in self.types:
87113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s.append("\ttype %s;" % type)
87213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for obj_class, perms in self.obj_classes.items():
87313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s.append("\tclass %s %s;" % (obj_class, perms.to_space_str()))
87413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for role in self.roles:
87513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s.append("\trole %s;" % role)
876628bcc69e23d96cec308bae5c70bebdeebeeeeccEric Paris        for bool in self.data:
87713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s.append("\tbool %s;" % bool)
87813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for user in self.users:
87913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            s.append("\tuser %s;" % user)
88013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        s.append("}")
88113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
88213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # Handle empty requires
88313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(s) == 2:
88413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return ""
88513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
88613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "\n".join(s)
88713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
88813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
88913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass ObjPermSet:
89013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, name):
89113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.name = name
89213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.perms = set()
89313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
89413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
89513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "define(`%s', `%s')" % (self.name, self.perms.to_space_str())
89613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
89713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass ClassMap:
89813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, obj_class, perms):
89913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.obj_class = obj_class
90013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.perms = perms
90113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
90213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
90313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return self.obj_class + ": " + self.perms
90413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
90513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass Comment:
90613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, l=None):
90713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if l:
90813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.lines = l
90913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
91013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            self.lines = []
91113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
91213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def to_string(self):
91313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # If there are no lines, treat this as a spacer between
91413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # policy statements and return a new line.
91513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(self.lines) == 0:
91613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return ""
91713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
91813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            out = []
91913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for line in self.lines:
92013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                out.append("#" + line)
92113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return "\n".join(out)
92213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
92313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def merge(self, other):
92413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(other.lines):
92513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for line in other.lines:
92613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if line != "":
92713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    self.lines.append(line)
92813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
92913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __str__(self):
93013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return self.to_string()
93113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
93213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
933