# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
#
# Copyright (C) 2006 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#

"""
This module provides knowledge object classes and permissions. It should
be used to keep this knowledge from leaking into the more generic parts of
the policy generation.
"""

# Objects that can be implicitly typed - these objects do
# not _have_ to be implicitly typed (e.g., sockets can be
# explicitly labeled), but they often are.
#
# File is in this list for /proc/self
#
# This list is useful when dealing with rules that have a
# type (or param) used as both a subject and object. For
# example:
#
#   allow httpd_t httpd_t : socket read;
#
# This rule makes sense because the socket was (presumably) created
# by a process with the type httpd_t.
implicitly_typed_objects = ["socket", "fd", "process", "file", "lnk_file", "fifo_file",
                            "dbus", "capability", "unix_stream_socket"]

#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#
#Information Flow
#
# All of the permissions in SELinux can be described in terms of
# information flow. For example, a read of a file is a flow of
# information from that file to the process reading. Viewing
# permissions in these terms can be used to model a varity of
# security properties.
#
# Here we have some infrastructure for understanding permissions
# in terms of information flow
#
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

# Information flow deals with information either flowing from a subject
# to and object ("write") or to a subject from an object ("read"). Read
# or write is described from the subject point-of-view. It is also possible
# for a permission to represent both a read and write (though the flow is
# typical asymettric in terms of bandwidth). It is also possible for
# permission to not flow information (meaning that the result is pure
# side-effect).
#
# The following constants are for representing the directionality
# of information flow.
FLOW_NONE  = 0
FLOW_READ  = 1
FLOW_WRITE = 2
FLOW_BOTH  = FLOW_READ | FLOW_WRITE

# These are used by the parser and for nice disply of the directions
str_to_dir = { "n" : FLOW_NONE, "r" : FLOW_READ, "w" : FLOW_WRITE, "b" : FLOW_BOTH }
dir_to_str = { FLOW_NONE : "n", FLOW_READ : "r", FLOW_WRITE : "w", FLOW_BOTH : "b" }

class PermMap:
    """A mapping between a permission and its information flow properties.

    PermMap represents the information flow properties of a single permission
    including the direction (read, write, etc.) and an abstract representation
    of the bandwidth of the flow (weight).
    """
    def __init__(self, perm, dir, weight):
        self.perm = perm
        self.dir = dir
        self.weight = weight

    def __repr__(self):
        return "<sepolgen.objectmodel.PermMap %s %s %d>" % (self.perm,
                                                           dir_to_str[self.dir],
                                                           self.weight)

class PermMappings:
    """The information flow properties of a set of object classes and permissions.

    PermMappings maps one or more classes and permissions to their PermMap objects
    describing their information flow charecteristics.
    """
    def __init__(self):
        self.classes = { }
        self.default_weight = 5
        self.default_dir = FLOW_BOTH

    def from_file(self, fd):
        """Read the permission mappings from a file. This reads the format used
        by Apol in the setools suite.
        """
        # This parsing is deliberitely picky and bails at the least error. It
        # is assumed that the permission map file will be shipped as part
        # of sepolgen and not user modified, so this is a reasonable design
        # choice. If user supplied permission mappings are needed the parser
        # should be made a little more robust and give better error messages.
        cur = None
        for line in fd:
            fields = line.split()
            if len(fields) == 0 or len(fields) == 1 or fields[0] == "#":
                continue
            if fields[0] == "class":
                c = fields[1]
                if c in self.classes:
                    raise ValueError("duplicate class in perm map")
                self.classes[c] = { }
                cur = self.classes[c]
            else:
                if len(fields) != 3:
                    raise ValueError("error in object classs permissions")
                if cur is None:
                    raise ValueError("permission outside of class")
                pm = PermMap(fields[0], str_to_dir[fields[1]], int(fields[2]))
                cur[pm.perm] = pm

    def get(self, obj, perm):
        """Get the permission map for the object permission.

        Returns:
          PermMap representing the permission
        Raises:
          KeyError if the object or permission is not defined
        """
        return self.classes[obj][perm]

    def getdefault(self, obj, perm):
        """Get the permission map for the object permission or a default.

        getdefault is the same as get except that a default PermMap is
        returned if the object class or permission is not defined. The
        default is FLOW_BOTH with a weight of 5.
        """
        try:
            pm = self.classes[obj][perm]
        except KeyError:
            return PermMap(perm, self.default_dir, self.default_weight)
        return pm

    def getdefault_direction(self, obj, perms):
        dir = FLOW_NONE
        for perm in perms:
            pm = self.getdefault(obj, perm)
            dir = dir | pm.dir
        return dir

    def getdefault_distance(self, obj, perms):
        total = 0
        for perm in perms:
            pm = self.getdefault(obj, perm)
            total += pm.weight

        return total



