#! /usr/bin/python -Es
# Copyright (C) 2011 Red Hat
# see file 'COPYING' for use and warranty information
#
# setrans is a tool for analyzing process transistions in SELinux policy
#
#    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; either version 2 of
#    the License, or (at your option) any later version.
#
#    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
#
#
import sepolicy
search = sepolicy.search
info = sepolicy.info
__all__ = ['setrans', ]


def _entrypoint(src):
    trans = search([sepolicy.ALLOW], {sepolicy.SOURCE: src})
    return map(lambda y: y[sepolicy.TARGET], filter(lambda x: "entrypoint" in x[sepolicy.PERMS], trans))


def _get_trans(src):
    return search([sepolicy.TRANSITION], {sepolicy.SOURCE: src, sepolicy.CLASS: "process"})


class setrans:

    def __init__(self, source, dest=None):
        self.seen = []
        self.sdict = {}
        self.source = source
        self.dest = dest
        self._process(self.source)

    def _process(self, source):
        if source in self.sdict:
            return self.sdict[source]
        self.sdict[source] = {}
        trans = _get_trans(source)
        if not trans:
            return
        self.sdict[source]["name"] = source
        if not self.dest:
            self.sdict[source]["map"] = trans
        else:
            self.sdict[source]["map"] = map(lambda y: y, filter(lambda x: x["transtype"] == self.dest, trans))
            self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest, source], trans))
            for s in self.sdict[source]["child"]:
                self._process(s)

    def out(self, name, header=""):
        buf = ""
        if name in self.seen:
            return buf
        self.seen.append(name)

        if "map" in self.sdict[name]:
            for t in self.sdict[name]["map"]:
                cond = sepolicy.get_conditionals(t["source"], t["transtype"], "process", ["transition"])
                if cond:
                    buf += "%s%s @ %s --> %s %s\n" % (header, t["source"], t["target"], t["transtype"], sepolicy.get_conditionals_format_text(cond))
                else:
                    buf += "%s%s @ %s --> %s\n" % (header, t["source"], t["target"], t["transtype"])

        if "child" in self.sdict[name]:
            for x in self.sdict[name]["child"]:
                buf += self.out(x, "%s%s ... " % (header, name))
        return buf

    def output(self):
        self.seen = []
        print self.out(self.source)
