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 Brindle"""
2113cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleThis module provides knowledge object classes and permissions. It should
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlebe used to keep this knowledge from leaking into the more generic parts of
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlethe policy generation.
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle"""
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Objects that can be implicitly typed - these objects do
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# not _have_ to be implicitly typed (e.g., sockets can be
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# explicitly labeled), but they often are.
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# File is in this list for /proc/self
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This list is useful when dealing with rules that have a
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# type (or param) used as both a subject and object. For
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# example:
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#   allow httpd_t httpd_t : socket read;
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This rule makes sense because the socket was (presumably) created
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# by a process with the type httpd_t.
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimplicitly_typed_objects = ["socket", "fd", "process", "file", "lnk_file", "fifo_file",
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                            "dbus", "capability", "unix_stream_socket"]
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#Information Flow
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# All of the permissions in SELinux can be described in terms of
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# information flow. For example, a read of a file is a flow of
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# information from that file to the process reading. Viewing
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# permissions in these terms can be used to model a varity of
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# security properties.
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Here we have some infrastructure for understanding permissions
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# in terms of information flow
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Information flow deals with information either flowing from a subject
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# to and object ("write") or to a subject from an object ("read"). Read
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# or write is described from the subject point-of-view. It is also possible
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# for a permission to represent both a read and write (though the flow is
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# typical asymettric in terms of bandwidth). It is also possible for
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# permission to not flow information (meaning that the result is pure
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# side-effect).
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# The following constants are for representing the directionality
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# of information flow.
6813cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_NONE  = 0
6913cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_READ  = 1
7013cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_WRITE = 2
7113cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleFLOW_BOTH  = FLOW_READ | FLOW_WRITE
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# These are used by the parser and for nice disply of the directions
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestr_to_dir = { "n" : FLOW_NONE, "r" : FLOW_READ, "w" : FLOW_WRITE, "b" : FLOW_BOTH }
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledir_to_str = { FLOW_NONE : "n", FLOW_READ : "r", FLOW_WRITE : "w", FLOW_BOTH : "b" }
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass PermMap:
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """A mapping between a permission and its information flow properties.
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    PermMap represents the information flow properties of a single permission
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    including the direction (read, write, etc.) and an abstract representation
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    of the bandwidth of the flow (weight).
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self, perm, dir, weight):
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.perm = perm
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.dir = dir
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.weight = weight
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __repr__(self):
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return "<sepolgen.objectmodel.PermMap %s %s %d>" % (self.perm,
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                                           dir_to_str[self.dir],
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                                           self.weight)
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleclass PermMappings:
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """The information flow properties of a set of object classes and permissions.
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    PermMappings maps one or more classes and permissions to their PermMap objects
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    describing their information flow charecteristics.
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    """
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def __init__(self):
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.classes = { }
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.default_weight = 5
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        self.default_dir = FLOW_BOTH
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def from_file(self, fd):
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Read the permission mappings from a file. This reads the format used
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        by Apol in the setools suite.
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # This parsing is deliberitely picky and bails at the least error. It
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # is assumed that the permission map file will be shipped as part
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # of sepolgen and not user modified, so this is a reasonable design
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # choice. If user supplied permission mappings are needed the parser
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        # should be made a little more robust and give better error messages.
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cur = None
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for line in fd:
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            fields = line.split()
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if len(fields) == 0 or len(fields) == 1 or fields[0] == "#":
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                continue
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if fields[0] == "class":
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                c = fields[1]
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if self.classes.has_key(c):
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    raise ValueError("duplicate class in perm map")
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                self.classes[c] = { }
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cur = self.classes[c]
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            else:
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if len(fields) != 3:
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    raise ValueError("error in object classs permissions")
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if cur is None:
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    raise ValueError("permission outside of class")
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                pm = PermMap(fields[0], str_to_dir[fields[1]], int(fields[2]))
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cur[pm.perm] = pm
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def get(self, obj, perm):
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Get the permission map for the object permission.
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Returns:
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle          PermMap representing the permission
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        Raises:
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle          KeyError if the object or permission is not defined
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return self.classes[obj][perm]
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def getdefault(self, obj, perm):
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """Get the permission map for the object permission or a default.
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        getdefault is the same as get except that a default PermMap is
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        returned if the object class or permission is not defined. The
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        default is FLOW_BOTH with a weight of 5.
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        """
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        try:
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            pm = self.classes[obj][perm]
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        except KeyError:
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            return PermMap(perm, self.default_dir, self.default_weight)
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return pm
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def getdefault_direction(self, obj, perms):
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        dir = FLOW_NONE
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for perm in perms:
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            pm = self.getdefault(obj, perm)
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            dir = dir | pm.dir
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return dir
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    def getdefault_distance(self, obj, perms):
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        total = 0
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for perm in perms:
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            pm = self.getdefault(obj, perm)
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            total += pm.weight
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return total
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
173