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

"""
Classes for representing and manipulating interfaces.
"""

import access
import refpolicy
import itertools
import objectmodel
import matching

from sepolgeni18n import _

import copy

class Param:
    """
    Object representing a paramater for an interface.
    """
    def __init__(self):
        self.__name = ""
        self.type = refpolicy.SRC_TYPE
        self.obj_classes = refpolicy.IdSet()
        self.required = True

    def set_name(self, name):
        if not access.is_idparam(name):
            raise ValueError("Name [%s] is not a param" % name)
        self.__name = name

    def get_name(self):
        return self.__name

    name = property(get_name, set_name)

    num = property(fget=lambda self: int(self.name[1:]))

    def __repr__(self):
        return "<sepolgen.policygen.Param instance [%s, %s, %s]>" % \
               (self.name, refpolicy.field_to_str[self.type], " ".join(self.obj_classes))


# Helper for extract perms
def __param_insert(name, type, av, params):
    ret = 0
    if name in params:
        p = params[name]
        # The entries are identical - we're done
        if type == p.type:
            return
        # Hanldle implicitly typed objects (like process)
        if (type == refpolicy.SRC_TYPE or type == refpolicy.TGT_TYPE) and \
           (p.type == refpolicy.TGT_TYPE or p.type == refpolicy.SRC_TYPE):
            #print name, refpolicy.field_to_str[p.type]
            # If the object is not implicitly typed, tell the
            # caller there is a likely conflict.
            ret = 1
            if av:
                avobjs = [av.obj_class]
            else:
                avobjs = []
            for obj in itertools.chain(p.obj_classes, avobjs):
                if obj in objectmodel.implicitly_typed_objects:
                    ret = 0
                    break
            # "Promote" to a SRC_TYPE as this is the likely usage.
            # We do this even if the above test fails on purpose
            # as there is really no sane way to resolve the conflict
            # here. The caller can take other actions if needed.
            p.type = refpolicy.SRC_TYPE
        else:
            # There is some conflict - no way to resolve it really
            # so we just leave the first entry and tell the caller
            # there was a conflict.
            ret = 1
    else:
        p = Param()
        p.name = name
        p.type = type
        params[p.name] = p

    if av:
        p.obj_classes.add(av.obj_class)
    return ret



def av_extract_params(av, params):
    """Extract the paramaters from an access vector.

    Extract the paramaters (in the form $N) from an access
    vector, storing them as Param objects in a dictionary.
    Some attempt is made at resolving conflicts with other
    entries in the dict, but if an unresolvable conflict is
    found it is reported to the caller.

    The goal here is to figure out how interface paramaters are
    actually used in the interface - e.g., that $1 is a domain used as
    a SRC_TYPE. In general an interface will look like this:

    interface(`foo', `
       allow $1 foo : file read;
    ')

    This is simple to figure out - $1 is a SRC_TYPE. A few interfaces
    are more complex, for example:

    interface(`foo_trans',`
       domain_auto_trans($1,fingerd_exec_t,fingerd_t)

       allow $1 fingerd_t:fd use;
       allow fingerd_t $1:fd use;
       allow fingerd_t $1:fifo_file rw_file_perms;
       allow fingerd_t $1:process sigchld;
    ')

    Here the usage seems ambigious, but it is not. $1 is still domain
    and therefore should be returned as a SRC_TYPE.

    Returns:
      0  - success
      1  - conflict found
    """
    ret = 0
    found_src = False
    if access.is_idparam(av.src_type):
        if __param_insert(av.src_type, refpolicy.SRC_TYPE, av, params) == 1:
            ret = 1

    if access.is_idparam(av.tgt_type):
        if __param_insert(av.tgt_type, refpolicy.TGT_TYPE, av, params) == 1:
            ret = 1

    if access.is_idparam(av.obj_class):
        if __param_insert(av.obj_class, refpolicy.OBJ_CLASS, av, params) == 1:
            ret = 1

    for perm in av.perms:
        if access.is_idparam(perm):
            if __param_insert(perm, PERM) == 1:
                ret = 1

    return ret

def role_extract_params(role, params):
    if access.is_idparam(role.role):
        return __param_insert(role.role, refpolicy.ROLE, None, params)
    
def type_rule_extract_params(rule, params):
    def extract_from_set(set, type):
        ret = 0
        for x in set:
            if access.is_idparam(x):
                if __param_insert(x, type, None, params):
                    ret = 1
        return ret

    ret = 0
    if extract_from_set(rule.src_types, refpolicy.SRC_TYPE):
        ret = 1

    if extract_from_set(rule.tgt_types, refpolicy.TGT_TYPE):
        ret = 1
        
    if extract_from_set(rule.obj_classes, refpolicy.OBJ_CLASS):
        ret = 1

    if access.is_idparam(rule.dest_type):
        if __param_insert(rule.dest_type, refpolicy.DEST_TYPE, None, params):
            ret = 1
            
    return ret

def ifcall_extract_params(ifcall, params):
    ret = 0
    for arg in ifcall.args:
        if access.is_idparam(arg):
            # Assume interface arguments are source types. Fairly safe
            # assumption for most interfaces
            if __param_insert(arg, refpolicy.SRC_TYPE, None, params):
                ret = 1

    return ret

class AttributeVector:
    def __init__(self):
        self.name = ""
        self.access = access.AccessVectorSet()

    def add_av(self, av):
        self.access.add_av(av)

class AttributeSet:
    def __init__(self):
        self.attributes = { }

    def add_attr(self, attr):
        self.attributes[attr.name] = attr

    def from_file(self, fd):
        def parse_attr(line):
            fields = line[1:-1].split()
            if len(fields) != 2 or fields[0] != "Attribute":
                raise SyntaxError("Syntax error Attribute statement %s" % line)
            a = AttributeVector()
            a.name = fields[1]

            return a

        a = None
        for line in fd:
            line = line[:-1]
            if line[0] == "[":
                if a:
                    self.add_attr(a)
                a = parse_attr(line)
            elif a:
                l = line.split(",")
                av = access.AccessVector(l)
                a.add_av(av)
        if a:
            self.add_attr(a)

class InterfaceVector:
    def __init__(self, interface=None, attributes={}):
        # Enabled is a loose concept currently - we are essentially
        # not enabling interfaces that we can't handle currently.
        # See InterfaceVector.add_ifv for more information.
        self.enabled = True
        self.name = ""
        # The access that is enabled by this interface - eventually
        # this will include indirect access from typeattribute
        # statements.
        self.access = access.AccessVectorSet()
        # Paramaters are stored in a dictionary (key: param name
        # value: Param object).
        self.params = { }
        if interface:
            self.from_interface(interface, attributes)
        self.expanded = False

    def from_interface(self, interface, attributes={}):
        self.name = interface.name

        # Add allow rules
        for avrule in interface.avrules():
            if avrule.rule_type != refpolicy.AVRule.ALLOW:
                continue
            # Handle some policy bugs
            if "dontaudit" in interface.name:
                #print "allow rule in interface: %s" % interface
                continue
            avs = access.avrule_to_access_vectors(avrule)
            for av in avs:
                self.add_av(av)

        # Add typeattribute access
        if attributes:
            for typeattribute in interface.typeattributes():
                for attr in typeattribute.attributes:
                    if not attributes.attributes.has_key(attr):
                        # print "missing attribute " + attr
                        continue
                    attr_vec = attributes.attributes[attr]
                    for a in attr_vec.access:
                        av = copy.copy(a)
                        if av.src_type == attr_vec.name:
                            av.src_type = typeattribute.type
                        if av.tgt_type == attr_vec.name:
                            av.tgt_type = typeattribute.type
                        self.add_av(av)


        # Extract paramaters from roles
        for role in interface.roles():
            if role_extract_params(role, self.params):
                pass
                #print "found conflicting role param %s for interface %s" % \
                #      (role.name, interface.name)
        # Extract paramaters from type rules
        for rule in interface.typerules():
            if type_rule_extract_params(rule, self.params):
                pass
                #print "found conflicting params in rule %s in interface %s" % \
                #      (str(rule), interface.name)

        for ifcall in interface.interface_calls():
            if ifcall_extract_params(ifcall, self.params):
                pass
                #print "found conflicting params in ifcall %s in interface %s" % \
                #      (str(ifcall), interface.name)
            

    def add_av(self, av):
        if av_extract_params(av, self.params) == 1:
            pass
            #print "found conflicting perms [%s]" % str(av)
        self.access.add_av(av)

    def to_string(self):
        s = []
        s.append("[InterfaceVector %s]" % self.name)
        for av in self.access:
            s.append(str(av))
        return "\n".join(s)

    def __str__(self):
        return self.__repr__()

    def __repr__(self):
        return "<InterfaceVector %s:%s>" % (self.name, self.enabled)


class InterfaceSet:
    def __init__(self, output=None):
        self.interfaces = { }
        self.tgt_type_map = { }
        self.tgt_type_all = []
        self.output = output

    def o(self, str):
        if self.output:
            self.output.write(str + "\n")

    def to_file(self, fd):
        for iv in self.interfaces.values():
            fd.write("[InterfaceVector %s " % iv.name)
            for param in iv.params.values():
                fd.write("%s:%s " % (param.name, refpolicy.field_to_str[param.type]))
            fd.write("]\n")
            avl = iv.access.to_list()
            for av in avl:
                fd.write(",".join(av))
                fd.write("\n")

    def from_file(self, fd):
        def parse_ifv(line):
            fields = line[1:-1].split()
            if len(fields) < 2 or fields[0] != "InterfaceVector":
                raise SyntaxError("Syntax error InterfaceVector statement %s" % line)
            ifv = InterfaceVector()
            ifv.name = fields[1]
            if len(fields) == 2:
                return
            for field in fields[2:]:
                p = field.split(":")
                if len(p) != 2:
                    raise SyntaxError("Invalid param in InterfaceVector statement %s" % line)
                param = Param()
                param.name = p[0]
                param.type = refpolicy.str_to_field[p[1]]
                ifv.params[param.name] = param
            return ifv

        ifv = None
        for line in fd:
            line = line[:-1]
            if line[0] == "[":
                if ifv:
                    self.add_ifv(ifv)
                ifv = parse_ifv(line)
            elif ifv:
                l = line.split(",")
                av = access.AccessVector(l)
                ifv.add_av(av)
        if ifv:
            self.add_ifv(ifv)

        self.index()

    def add_ifv(self, ifv):
        self.interfaces[ifv.name] = ifv

    def index(self):
        for ifv in self.interfaces.values():
            tgt_types = set()
            for av in ifv.access:
                if access.is_idparam(av.tgt_type):
                    self.tgt_type_all.append(ifv)
                    tgt_types = set()
                    break
                tgt_types.add(av.tgt_type)

            for type in tgt_types:
                l = self.tgt_type_map.setdefault(type, [])
                l.append(ifv)

    def add(self, interface, attributes={}):
        ifv = InterfaceVector(interface, attributes)
        self.add_ifv(ifv)

    def add_headers(self, headers, output=None, attributes={}):
        for i in itertools.chain(headers.interfaces(), headers.templates()):
            self.add(i, attributes)

        self.expand_ifcalls(headers)
        self.index()

    def map_param(self, id, ifcall):
        if access.is_idparam(id):
            num = int(id[1:])
            if num > len(ifcall.args):
                # Tell caller to drop this because it must have
                # been generated from an optional param.
                return None
            else:
                arg = ifcall.args[num - 1]
                if isinstance(arg, list):
                    return arg
                else:
                    return [arg]
        else:
            return [id]

    def map_add_av(self, ifv, av, ifcall):
        src_types = self.map_param(av.src_type, ifcall)
        if src_types is None:
            return

        tgt_types = self.map_param(av.tgt_type, ifcall)
        if tgt_types is None:
            return

        obj_classes = self.map_param(av.obj_class, ifcall)
        if obj_classes is None:
            return

        new_perms = refpolicy.IdSet()
        for perm in av.perms:
            p = self.map_param(perm, ifcall)
            if p is None:
                continue
            else:
                new_perms.update(p)
        if len(new_perms) == 0:
            return

        for src_type in src_types:
            for tgt_type in tgt_types:
                for obj_class in obj_classes:
                    ifv.access.add(src_type, tgt_type, obj_class, new_perms)

    def do_expand_ifcalls(self, interface, if_by_name):
        # Descend an interface call tree adding the access
        # from each interface. This is a depth first walk
        # of the tree.

        stack = [(interface, None)]
        ifv = self.interfaces[interface.name]
        ifv.expanded = True

        while len(stack) > 0:
            cur, cur_ifcall = stack.pop(-1)

            cur_ifv = self.interfaces[cur.name]
            if cur != interface:

                for av in cur_ifv.access:
                    self.map_add_av(ifv, av, cur_ifcall)

                # If we have already fully expanded this interface
                # there is no reason to descend further.
                if cur_ifv.expanded:
                    continue

            for ifcall in cur.interface_calls():
                if ifcall.ifname == interface.name:
                    self.o(_("Found circular interface class"))
                    return
                try:
                    newif = if_by_name[ifcall.ifname]
                except KeyError:
                    self.o(_("Missing interface definition for %s" % ifcall.ifname))
                    continue

                stack.append((newif, ifcall))


    def expand_ifcalls(self, headers):
        # Create a map of interface names to interfaces -
        # this mirrors the interface vector map we already
        # have.
        if_by_name = { }

        for i in itertools.chain(headers.interfaces(), headers.templates()):
            if_by_name[i.name] = i


        for interface in itertools.chain(headers.interfaces(), headers.templates()):
            self.do_expand_ifcalls(interface, if_by_name)

